diff --git a/JavaScriptCore/runtime/ArgList.cpp b/JavaScriptCore/runtime/ArgList.cpp
new file mode 100644
index 0000000..7675b20
--- /dev/null
+++ b/JavaScriptCore/runtime/ArgList.cpp
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ArgList.h"
+
+#include "JSValue.h"
+#include "JSCell.h"
+
+using std::min;
+
+namespace JSC {
+
+void ArgList::getSlice(int startIndex, ArgList& result) const
+{
+    ASSERT(!result.m_isReadOnly);
+
+    const_iterator start = min(begin() + startIndex, end());
+    result.m_vector.appendRange(start, end());
+    result.m_size = result.m_vector.size();
+    result.m_buffer = result.m_vector.data();
+}
+
+void ArgList::markLists(ListSet& markSet)
+{
+    ListSet::iterator end = markSet.end();
+    for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
+        ArgList* list = *it;
+
+        iterator end2 = list->end();
+        for (iterator it2 = list->begin(); it2 != end2; ++it2)
+            if (!(*it2).marked())
+                (*it2).mark();
+    }
+}
+
+void ArgList::slowAppend(JSValue* v)
+{
+    // As long as our size stays within our Vector's inline 
+    // capacity, all our values are allocated on the stack, and 
+    // therefore don't need explicit marking. Once our size exceeds
+    // our Vector's inline capacity, though, our values move to the 
+    // heap, where they do need explicit marking.
+    if (!m_markSet) {
+        // We can only register for explicit marking once we know which heap
+        // is the current one, i.e., when a non-immediate value is appended.
+        if (Heap* heap = Heap::heap(v)) {
+            ListSet& markSet = heap->markListSet();
+            markSet.add(this);
+            m_markSet = &markSet;
+        }
+    }
+
+    if (m_vector.size() < m_vector.capacity()) {
+        m_vector.uncheckedAppend(v);
+        return;
+    }
+
+    // 4x growth would be excessive for a normal vector, but it's OK for Lists 
+    // because they're short-lived.
+    m_vector.reserveCapacity(m_vector.capacity() * 4);
+    
+    m_vector.uncheckedAppend(v);
+    m_buffer = m_vector.data();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ArgList.h b/JavaScriptCore/runtime/ArgList.h
new file mode 100644
index 0000000..44446aa
--- /dev/null
+++ b/JavaScriptCore/runtime/ArgList.h
@@ -0,0 +1,161 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Computer, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ArgList_h
+#define ArgList_h
+
+#include "JSImmediate.h"
+#include "Register.h"
+
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+    
+    class ArgList : Noncopyable {
+    private:
+        static const unsigned inlineCapacity = 8;
+        typedef Vector<Register, inlineCapacity> VectorType;
+        typedef HashSet<ArgList*> ListSet;
+
+    public:
+        typedef VectorType::iterator iterator;
+        typedef VectorType::const_iterator const_iterator;
+
+        // Constructor for a read-write list, to which you may append values.
+        // FIXME: Remove all clients of this API, then remove this API.
+        ArgList()
+            : m_markSet(0)
+#ifndef NDEBUG
+            , m_isReadOnly(false)
+#endif
+        {
+            m_buffer = m_vector.data();
+            m_size = 0;
+        }
+
+        // Constructor for a read-only list whose data has already been allocated elsewhere.
+        ArgList(Register* buffer, size_t size)
+            : m_buffer(buffer)
+            , m_size(size)
+            , m_markSet(0)
+#ifndef NDEBUG
+            , m_isReadOnly(true)
+#endif
+        {
+        }
+
+        void initialize(Register* buffer, size_t size)
+        {
+            ASSERT(!m_markSet);
+            ASSERT(isEmpty());
+
+            m_buffer = buffer;
+            m_size = size;
+#ifndef NDEBUG
+            m_isReadOnly = true;
+#endif
+        }
+
+        ~ArgList()
+        {
+            if (m_markSet)
+                m_markSet->remove(this);
+        }
+
+        size_t size() const { return m_size; }
+        bool isEmpty() const { return !m_size; }
+
+        JSValue* at(ExecState* exec, size_t i) const
+        {
+            if (i < m_size)
+                return m_buffer[i].jsValue(exec);
+            return jsUndefined();
+        }
+
+        void clear()
+        {
+            m_vector.clear();
+            m_buffer = 0;
+            m_size = 0;
+        }
+
+        void append(JSValue* v)
+        {
+            ASSERT(!m_isReadOnly);
+            
+            if (m_size < inlineCapacity) {
+                m_vector.uncheckedAppend(v);
+                ++m_size;
+            } else {
+                // Putting this case all in one function measurably improves
+                // the performance of the fast "just append to inline buffer" case.
+                slowAppend(v);
+                ++m_size;
+            }
+        }
+
+        void getSlice(int startIndex, ArgList& result) const;
+
+        iterator begin() { return m_buffer; }
+        iterator end() { return m_buffer + m_size; }
+
+        const_iterator begin() const { return m_buffer; }
+        const_iterator end() const { return m_buffer + m_size; }
+
+        static void markLists(ListSet&);
+
+    private:
+        void slowAppend(JSValue*);
+        
+        Register* m_buffer;
+        size_t m_size;
+
+        VectorType m_vector;
+        ListSet* m_markSet;
+#ifndef NDEBUG
+        bool m_isReadOnly;
+#endif
+
+    private:
+        // Prohibits new / delete, which would break GC.
+        friend class JSGlobalData;
+        
+        void* operator new(size_t size)
+        {
+            return fastMalloc(size);
+        }
+        void operator delete(void* p)
+        {
+            fastFree(p);
+        }
+
+        void* operator new[](size_t);
+        void operator delete[](void*);
+
+        void* operator new(size_t, void*);
+        void operator delete(void*, size_t);
+    };
+
+} // namespace JSC
+
+#endif // ArgList_h
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
new file mode 100644
index 0000000..fe1de62
--- /dev/null
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -0,0 +1,232 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "Arguments.h"
+
+#include "JSActivation.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+
+using namespace std;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(Arguments);
+
+const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
+
+Arguments::~Arguments()
+{
+    if (d->extraArguments != d->extraArgumentsFixedBuffer)
+        delete [] d->extraArguments;
+}
+
+void Arguments::mark()
+{
+    JSObject::mark();
+
+    if (d->registerArray) {
+        for (unsigned i = 0; i < d->numParameters; ++i) {
+            if (!d->registerArray[i].marked())
+                d->registerArray[i].mark();
+        }
+    }
+
+    if (d->extraArguments) {
+        unsigned numExtraArguments = d->numArguments - d->numParameters;
+        for (unsigned i = 0; i < numExtraArguments; ++i) {
+            if (!d->extraArguments[i].marked())
+                d->extraArguments[i].mark();
+        }
+    }
+
+    if (!d->callee->marked())
+        d->callee->mark();
+
+    if (d->activation && !d->activation->marked())
+        d->activation->mark();
+}
+
+void Arguments::fillArgList(ExecState* exec, ArgList& args)
+{
+    if (LIKELY(!d->deletedArguments)) {
+        if (LIKELY(!d->numParameters)) {
+            args.initialize(d->extraArguments, d->numArguments);
+            return;
+        }
+
+        if (d->numParameters == d->numArguments) {
+            args.initialize(&d->registers[d->firstParameterIndex], d->numArguments);
+            return;
+        }
+
+        unsigned parametersLength = min(d->numParameters, d->numArguments);
+        unsigned i = 0;
+        for (; i < parametersLength; ++i)
+            args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
+        for (; i < d->numArguments; ++i)
+            args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
+        return;
+    }
+
+    unsigned parametersLength = min(d->numParameters, d->numArguments);
+    unsigned i = 0;
+    for (; i < parametersLength; ++i) {
+        if (!d->deletedArguments[i])
+            args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
+        else
+            args.append(get(exec, i));
+    }
+    for (; i < d->numArguments; ++i) {
+        if (!d->deletedArguments[i])
+            args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
+        else
+            args.append(get(exec, i));
+    }
+}
+
+bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
+{
+    if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
+        if (i < d->numParameters) {
+            slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
+        } else
+            slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
+        return true;
+    }
+
+    return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::from(i)), slot);
+}
+
+bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    bool isArrayIndex;
+    unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+    if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
+        if (i < d->numParameters) {
+            slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
+        } else
+            slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
+        return true;
+    }
+
+    if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) {
+        slot.setValue(jsNumber(exec, d->numArguments));
+        return true;
+    }
+
+    if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
+        slot.setValue(d->callee);
+        return true;
+    }
+
+    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+void Arguments::put(ExecState* exec, unsigned i, JSValue* value, PutPropertySlot& slot)
+{
+    if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
+        if (i < d->numParameters)
+            d->registers[d->firstParameterIndex + i] = value;
+        else
+            d->extraArguments[i - d->numParameters] = value;
+        return;
+    }
+
+    JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot);
+}
+
+void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    bool isArrayIndex;
+    unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+    if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
+        if (i < d->numParameters)
+            d->registers[d->firstParameterIndex + i] = value;
+        else
+            d->extraArguments[i - d->numParameters] = value;
+        return;
+    }
+
+    if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
+        d->overrodeLength = true;
+        putDirect(propertyName, value, DontEnum);
+        return;
+    }
+
+    if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
+        d->overrodeCallee = true;
+        putDirect(propertyName, value, DontEnum);
+        return;
+    }
+
+    JSObject::put(exec, propertyName, value, slot);
+}
+
+bool Arguments::deleteProperty(ExecState* exec, unsigned i) 
+{
+    if (i < d->numArguments) {
+        if (!d->deletedArguments) {
+            d->deletedArguments.set(new bool[d->numArguments]);
+            memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
+        }
+        if (!d->deletedArguments[i]) {
+            d->deletedArguments[i] = true;
+            return true;
+        }
+    }
+
+    return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i)));
+}
+
+bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) 
+{
+    bool isArrayIndex;
+    unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+    if (isArrayIndex && i < d->numArguments) {
+        if (!d->deletedArguments) {
+            d->deletedArguments.set(new bool[d->numArguments]);
+            memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
+        }
+        if (!d->deletedArguments[i]) {
+            d->deletedArguments[i] = true;
+            return true;
+        }
+    }
+
+    if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
+        d->overrodeLength = true;
+        return true;
+    }
+
+    if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
+        d->overrodeCallee = true;
+        return true;
+    }
+
+    return JSObject::deleteProperty(exec, propertyName);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h
new file mode 100644
index 0000000..93cc64f
--- /dev/null
+++ b/JavaScriptCore/runtime/Arguments.h
@@ -0,0 +1,227 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef Arguments_h
+#define Arguments_h
+
+#include "JSActivation.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "Machine.h"
+
+namespace JSC {
+
+    struct ArgumentsData : Noncopyable {
+        JSActivation* activation;
+
+        unsigned numParameters;
+        ptrdiff_t firstParameterIndex;
+        unsigned numArguments;
+
+        Register* registers;
+        OwnArrayPtr<Register> registerArray;
+
+        Register* extraArguments;
+        OwnArrayPtr<bool> deletedArguments;
+        Register extraArgumentsFixedBuffer[4];
+
+        JSFunction* callee;
+        bool overrodeLength : 1;
+        bool overrodeCallee : 1;
+    };
+
+
+    class Arguments : public JSObject {
+    public:
+        enum NoParametersType { NoParameters };
+
+        Arguments(CallFrame*);
+        Arguments(CallFrame*, NoParametersType);
+        virtual ~Arguments();
+
+        static const ClassInfo info;
+
+        virtual void mark();
+
+        void fillArgList(ExecState*, ArgList&);
+
+        void copyRegisters();
+        bool isTornOff() const { return d->registerArray; }
+        void setActivation(JSActivation* activation)
+        {
+            d->activation = activation;
+            d->registers = &activation->registerAt(0);
+        }
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype) 
+        { 
+            return StructureID::create(prototype, TypeInfo(ObjectType)); 
+        }
+
+    private:
+        void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue*, PutPropertySlot&);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+        virtual bool deleteProperty(ExecState*, unsigned propertyName);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        void init(CallFrame*);
+
+        OwnPtr<ArgumentsData> d;
+    };
+
+    Arguments* asArguments(JSValue*);
+
+    inline Arguments* asArguments(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&Arguments::info));
+        return static_cast<Arguments*>(asObject(value));
+    }
+
+    ALWAYS_INLINE void Arguments::getArgumentsData(CallFrame* callFrame, JSFunction*& function, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc)
+    {
+        function = callFrame->callee();
+    
+        CodeBlock* codeBlock = &function->m_body->generatedByteCode();
+        int numParameters = codeBlock->numParameters;
+        argc = callFrame->argumentCount();
+
+        if (argc <= numParameters)
+            argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this"
+        else
+            argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc + 1; // + 1 to skip "this"
+
+        argc -= 1; // - 1 to skip "this"
+        firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this"
+    }
+
+    inline Arguments::Arguments(CallFrame* callFrame)
+        : JSObject(callFrame->lexicalGlobalObject()->argumentsStructure())
+        , d(new ArgumentsData)
+    {
+        JSFunction* callee;
+        ptrdiff_t firstParameterIndex;
+        Register* argv;
+        int numArguments;
+        getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
+
+        d->numParameters = callee->m_body->parameterCount();
+        d->firstParameterIndex = firstParameterIndex;
+        d->numArguments = numArguments;
+
+        d->activation = 0;
+        d->registers = callFrame->registers();
+
+        Register* extraArguments;
+        if (d->numArguments <= d->numParameters)
+            extraArguments = 0;
+        else {
+            unsigned numExtraArguments = d->numArguments - d->numParameters;
+            if (numExtraArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register))
+                extraArguments = new Register[numExtraArguments];
+            else
+                extraArguments = d->extraArgumentsFixedBuffer;
+            for (unsigned i = 0; i < numExtraArguments; ++i)
+                extraArguments[i] = argv[d->numParameters + i];
+        }
+
+        d->extraArguments = extraArguments;
+
+        d->callee = callee;
+        d->overrodeLength = false;
+        d->overrodeCallee = false;
+    }
+
+    inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
+        : JSObject(callFrame->lexicalGlobalObject()->argumentsStructure())
+        , d(new ArgumentsData)
+    {
+        ASSERT(!callFrame->callee()->m_body->parameterCount());
+
+        unsigned numArguments = callFrame->argumentCount() - 1;
+
+        d->numParameters = 0;
+        d->numArguments = numArguments;
+        d->activation = 0;
+
+        Register* extraArguments;
+        if (numArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register))
+            extraArguments = new Register[numArguments];
+        else
+            extraArguments = d->extraArgumentsFixedBuffer;
+
+        Register* argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numArguments - 1;
+        for (unsigned i = 0; i < numArguments; ++i)
+            extraArguments[i] = argv[i];
+
+        d->extraArguments = extraArguments;
+
+        d->callee = callFrame->callee();
+        d->overrodeLength = false;
+        d->overrodeCallee = false;
+    }
+
+    inline void Arguments::copyRegisters()
+    {
+        ASSERT(!isTornOff());
+
+        if (!d->numParameters)
+            return;
+
+        int registerOffset = d->numParameters + RegisterFile::CallFrameHeaderSize;
+        size_t registerArraySize = d->numParameters;
+
+        Register* registerArray = new Register[registerArraySize];
+        memcpy(registerArray, d->registers - registerOffset, registerArraySize * sizeof(Register));
+        d->registerArray.set(registerArray);
+        d->registers = registerArray + registerOffset;
+    }
+
+    // This JSActivation function is defined here so it can get at Arguments::setRegisters.
+    inline void JSActivation::copyRegisters(Arguments* arguments)
+    {
+        ASSERT(!d()->registerArray);
+
+        size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
+        size_t numVars = d()->functionBody->generatedByteCode().numVars;
+        size_t numLocals = numVars + numParametersMinusThis;
+
+        if (!numLocals)
+            return;
+
+        int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
+        size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
+
+        Register* registerArray = copyRegisterArray(d()->registers - registerOffset, registerArraySize);
+        setRegisters(registerArray + registerOffset, registerArray);
+        if (arguments && !arguments->isTornOff())
+            static_cast<Arguments*>(arguments)->setActivation(this);
+    }
+
+} // namespace JSC
+
+#endif // Arguments_h
diff --git a/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp
new file mode 100644
index 0000000..5784af0
--- /dev/null
+++ b/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ *  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 "ArrayConstructor.h"
+
+#include "ArrayPrototype.h"
+#include "JSArray.h"
+#include "lookup.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
+
+ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<StructureID> structure, ArrayPrototype* arrayPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, arrayPrototype->classInfo()->className))
+{
+    // ECMA 15.4.3.1 Array.prototype
+    putDirectWithoutTransition(exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
+
+    // no. of arguments for constructor
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
+}
+
+static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
+{
+    // a single numeric argument denotes the array size (!)
+    if (args.size() == 1 && args.at(exec, 0)->isNumber()) {
+        uint32_t n = args.at(exec, 0)->toUInt32(exec);
+        if (n != args.at(exec, 0)->toNumber(exec))
+            return throwError(exec, RangeError, "Array size is not a small enough positive integer.");
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n);
+    }
+
+    // otherwise the array is constructed with the arguments in it
+    return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), args);
+}
+
+static JSObject* constructWithArrayConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructArrayWithSizeQuirk(exec, args);
+}
+
+// ECMA 15.4.2
+ConstructType ArrayConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithArrayConstructor;
+    return ConstructTypeHost;
+}
+
+static JSValue* callArrayConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructArrayWithSizeQuirk(exec, args);
+}
+
+// ECMA 15.6.1
+CallType ArrayConstructor::getCallData(CallData& callData)
+{
+    // equivalent to 'new Array(....)'
+    callData.native.function = callArrayConstructor;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ArrayConstructor.h b/JavaScriptCore/runtime/ArrayConstructor.h
new file mode 100644
index 0000000..6f0f866
--- /dev/null
+++ b/JavaScriptCore/runtime/ArrayConstructor.h
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef ArrayConstructor_h
+#define ArrayConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class ArrayPrototype;
+
+    class ArrayConstructor : public InternalFunction {
+    public:
+        ArrayConstructor(ExecState*, PassRefPtr<StructureID>, ArrayPrototype*);
+
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+} // namespace JSC
+
+#endif // ArrayConstructor_h
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
new file mode 100644
index 0000000..5280784
--- /dev/null
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -0,0 +1,794 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ *  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 "ArrayPrototype.h"
+
+#include "Machine.h"
+#include "ObjectPrototype.h"
+#include "lookup.h"
+#include "operations.h"
+#include <algorithm>
+#include <wtf/Assertions.h>
+#include <wtf/HashSet.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
+
+static JSValue* arrayProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncJoin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncPop(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncPush(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncReverse(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncShift(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSlice(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSort(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSplice(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncUnShift(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncEvery(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncForEach(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncSome(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncFilter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncMap(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "ArrayPrototype.lut.h"
+
+namespace JSC {
+
+// ------------------------------ ArrayPrototype ----------------------------
+
+const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::arrayTable};
+
+/* Source for ArrayPrototype.lut.h
+@begin arrayTable 16
+  toString       arrayProtoFuncToString       DontEnum|Function 0
+  toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0
+  concat         arrayProtoFuncConcat         DontEnum|Function 1
+  join           arrayProtoFuncJoin           DontEnum|Function 1
+  pop            arrayProtoFuncPop            DontEnum|Function 0
+  push           arrayProtoFuncPush           DontEnum|Function 1
+  reverse        arrayProtoFuncReverse        DontEnum|Function 0
+  shift          arrayProtoFuncShift          DontEnum|Function 0
+  slice          arrayProtoFuncSlice          DontEnum|Function 2
+  sort           arrayProtoFuncSort           DontEnum|Function 1
+  splice         arrayProtoFuncSplice         DontEnum|Function 2
+  unshift        arrayProtoFuncUnShift        DontEnum|Function 1
+  every          arrayProtoFuncEvery          DontEnum|Function 1
+  forEach        arrayProtoFuncForEach        DontEnum|Function 1
+  some           arrayProtoFuncSome           DontEnum|Function 1
+  indexOf        arrayProtoFuncIndexOf        DontEnum|Function 1
+  lastIndexOf    arrayProtoFuncLastIndexOf    DontEnum|Function 1
+  filter         arrayProtoFuncFilter         DontEnum|Function 1
+  map            arrayProtoFuncMap            DontEnum|Function 1
+@end
+*/
+
+// ECMA 15.4.4
+ArrayPrototype::ArrayPrototype(PassRefPtr<StructureID> structure)
+    : JSArray(structure)
+{
+}
+
+bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, slot);
+}
+
+// ------------------------------ Array Functions ----------------------------
+
+// Helper function
+static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
+{
+    PropertySlot slot(obj);
+    if (!obj->getPropertySlot(exec, index, slot))
+        return noValue();
+    return slot.getValue(exec, index);
+}
+
+static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue* value)
+{
+    PutPropertySlot slot;
+    obj->put(exec, propertyName, value, slot);
+}
+
+JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&JSArray::info))
+        return throwError(exec, TypeError);
+    JSObject* thisObj = asArray(thisValue);
+
+    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
+    if (arrayVisitedElements.size() > MaxReentryDepth)
+        return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+
+    bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
+    if (alreadyVisited)
+        return jsEmptyString(exec); // return an empty string, avoiding infinite recursion.
+
+    Vector<UChar, 256> strBuffer;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length; k++) {
+        if (k >= 1)
+            strBuffer.append(',');
+        if (!strBuffer.data()) {
+            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+            exec->setException(error);
+            break;
+        }
+
+        JSValue* element = thisObj->get(exec, k);
+        if (element->isUndefinedOrNull())
+            continue;
+
+        UString str = element->toString(exec);
+        strBuffer.append(str.data(), str.size());
+
+        if (!strBuffer.data()) {
+            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+            exec->setException(error);
+        }
+
+        if (exec->hadException())
+            break;
+    }
+    arrayVisitedElements.remove(thisObj);
+    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+}
+
+JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&JSArray::info))
+        return throwError(exec, TypeError);
+    JSObject* thisObj = asArray(thisValue);
+
+    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
+    if (arrayVisitedElements.size() > MaxReentryDepth)
+        return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+
+    bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
+    if (alreadyVisited)
+        return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
+
+    Vector<UChar, 256> strBuffer;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length; k++) {
+        if (k >= 1)
+            strBuffer.append(',');
+        if (!strBuffer.data()) {
+            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+            exec->setException(error);
+            break;
+        }
+
+        JSValue* element = thisObj->get(exec, k);
+        if (element->isUndefinedOrNull())
+            continue;
+
+        JSObject* o = element->toObject(exec);
+        JSValue* conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
+        UString str;
+        CallData callData;
+        CallType callType = conversionFunction->getCallData(callData);
+        if (callType != CallTypeNone)
+            str = call(exec, conversionFunction, callType, callData, element, exec->emptyList())->toString(exec);
+        else
+            str = element->toString(exec);
+        strBuffer.append(str.data(), str.size());
+
+        if (!strBuffer.data()) {
+            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+            exec->setException(error);
+        }
+
+        if (exec->hadException())
+            break;
+    }
+    arrayVisitedElements.remove(thisObj);
+    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+}
+
+JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
+    if (arrayVisitedElements.size() > MaxReentryDepth)
+        return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+
+    bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
+    if (alreadyVisited)
+        return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
+
+    Vector<UChar, 256> strBuffer;
+
+    UChar comma = ',';
+    UString separator = args.at(exec, 0)->isUndefined() ? UString(&comma, 1) : args.at(exec, 0)->toString(exec);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length; k++) {
+        if (k >= 1)
+            strBuffer.append(separator.data(), separator.size());
+        if (!strBuffer.data()) {
+            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+            exec->setException(error);
+            break;
+        }
+
+        JSValue* element = thisObj->get(exec, k);
+        if (element->isUndefinedOrNull())
+            continue;
+
+        UString str = element->toString(exec);
+        strBuffer.append(str.data(), str.size());
+
+        if (!strBuffer.data()) {
+            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+            exec->setException(error);
+        }
+
+        if (exec->hadException())
+            break;
+    }
+    arrayVisitedElements.remove(thisObj);
+    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+}
+
+JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSArray* arr = constructEmptyArray(exec);
+    int n = 0;
+    JSValue* curArg = thisValue->toThisObject(exec);
+    ArgList::const_iterator it = args.begin();
+    ArgList::const_iterator end = args.end();
+    while (1) {
+        if (curArg->isObject(&JSArray::info)) {
+            JSArray* curArray = asArray(curArg);
+            unsigned length = curArray->length();
+            for (unsigned k = 0; k < length; ++k) {
+                if (JSValue* v = getProperty(exec, curArray, k))
+                    arr->put(exec, n, v);
+                n++;
+            }
+        } else {
+            arr->put(exec, n, curArg);
+            n++;
+        }
+        if (it == end)
+            break;
+        curArg = (*it).jsValue(exec);
+        ++it;
+    }
+    arr->setLength(n);
+    return arr;
+}
+
+JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (exec->machine()->isJSArray(thisValue))
+        return asArray(thisValue)->pop();
+
+    JSObject* thisObj = thisValue->toThisObject(exec);
+    JSValue* result;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    if (length == 0) {
+        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
+        result = jsUndefined();
+    } else {
+        result = thisObj->get(exec, length - 1);
+        thisObj->deleteProperty(exec, length - 1);
+        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1));
+    }
+    return result;
+}
+
+JSValue* arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (exec->machine()->isJSArray(thisValue) && args.size() == 1) {
+        JSArray* array = asArray(thisValue);
+        array->push(exec, args.begin()->jsValue(exec));
+        return jsNumber(exec, array->length());
+    }
+
+    JSObject* thisObj = thisValue->toThisObject(exec);
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned n = 0; n < args.size(); n++)
+        thisObj->put(exec, length + n, args.at(exec, n));
+    length += args.size();
+    putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
+    return jsNumber(exec, length);
+}
+
+JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    unsigned middle = length / 2;
+
+    for (unsigned k = 0; k < middle; k++) {
+        unsigned lk1 = length - k - 1;
+        JSValue* obj2 = getProperty(exec, thisObj, lk1);
+        JSValue* obj = getProperty(exec, thisObj, k);
+
+        if (obj2)
+            thisObj->put(exec, k, obj2);
+        else
+            thisObj->deleteProperty(exec, k);
+
+        if (obj)
+            thisObj->put(exec, lk1, obj);
+        else
+            thisObj->deleteProperty(exec, lk1);
+    }
+    return thisObj;
+}
+
+JSValue* arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+    JSValue* result;
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    if (length == 0) {
+        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
+        result = jsUndefined();
+    } else {
+        result = thisObj->get(exec, 0);
+        for (unsigned k = 1; k < length; k++) {
+            if (JSValue* obj = getProperty(exec, thisObj, k))
+                thisObj->put(exec, k - 1, obj);
+            else
+                thisObj->deleteProperty(exec, k - 1);
+        }
+        thisObj->deleteProperty(exec, length - 1);
+        putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1));
+    }
+    return result;
+}
+
+JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
+
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    // We return a new array
+    JSArray* resObj = constructEmptyArray(exec);
+    JSValue* result = resObj;
+    double begin = args.at(exec, 0)->toInteger(exec);
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    if (begin >= 0) {
+        if (begin > length)
+            begin = length;
+    } else {
+        begin += length;
+        if (begin < 0)
+            begin = 0;
+    }
+    double end;
+    if (args.at(exec, 1)->isUndefined())
+        end = length;
+    else {
+        end = args.at(exec, 1)->toInteger(exec);
+        if (end < 0) {
+            end += length;
+            if (end < 0)
+                end = 0;
+        } else {
+            if (end > length)
+                end = length;
+        }
+    }
+
+    int n = 0;
+    int b = static_cast<int>(begin);
+    int e = static_cast<int>(end);
+    for (int k = b; k < e; k++, n++) {
+        if (JSValue* v = getProperty(exec, thisObj, k))
+            resObj->put(exec, n, v);
+    }
+    resObj->setLength(n);
+    return result;
+}
+
+JSValue* arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args.at(exec, 0);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+
+    if (thisObj->classInfo() == &JSArray::info) {
+        if (callType != CallTypeNone)
+            asArray(thisObj)->sort(exec, function, callType, callData);
+        else
+            asArray(thisObj)->sort(exec);
+        return thisObj;
+    }
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+
+    if (!length)
+        return thisObj;
+
+    // "Min" sort. Not the fastest, but definitely less code than heapsort
+    // or quicksort, and much less swapping than bubblesort/insertionsort.
+    for (unsigned i = 0; i < length - 1; ++i) {
+        JSValue* iObj = thisObj->get(exec, i);
+        unsigned themin = i;
+        JSValue* minObj = iObj;
+        for (unsigned j = i + 1; j < length; ++j) {
+            JSValue* jObj = thisObj->get(exec, j);
+            double compareResult;
+            if (jObj->isUndefined())
+                compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
+            else if (minObj->isUndefined())
+                compareResult = -1;
+            else if (callType != CallTypeNone) {
+                ArgList l;
+                l.append(jObj);
+                l.append(minObj);
+                compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l)->toNumber(exec);
+            } else
+                compareResult = (jObj->toString(exec) < minObj->toString(exec)) ? -1 : 1;
+
+            if (compareResult < 0) {
+                themin = j;
+                minObj = jObj;
+            }
+        }
+        // Swap themin and i
+        if (themin > i) {
+            thisObj->put(exec, i, minObj);
+            thisObj->put(exec, themin, iObj);
+        }
+    }
+    return thisObj;
+}
+
+JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    // 15.4.4.12
+    JSArray* resObj = constructEmptyArray(exec);
+    JSValue* result = resObj;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    if (!args.size())
+        return jsUndefined();
+    int begin = args.at(exec, 0)->toUInt32(exec);
+    if (begin < 0)
+        begin = std::max<int>(begin + length, 0);
+    else
+        begin = std::min<int>(begin, length);
+
+    unsigned deleteCount;
+    if (args.size() > 1)
+        deleteCount = std::min<int>(std::max<int>(args.at(exec, 1)->toUInt32(exec), 0), length - begin);
+    else
+        deleteCount = length - begin;
+
+    for (unsigned k = 0; k < deleteCount; k++) {
+        if (JSValue* v = getProperty(exec, thisObj, k + begin))
+            resObj->put(exec, k, v);
+    }
+    resObj->setLength(deleteCount);
+
+    unsigned additionalArgs = std::max<int>(args.size() - 2, 0);
+    if (additionalArgs != deleteCount) {
+        if (additionalArgs < deleteCount) {
+            for (unsigned k = begin; k < length - deleteCount; ++k) {
+                if (JSValue* v = getProperty(exec, thisObj, k + deleteCount))
+                    thisObj->put(exec, k + additionalArgs, v);
+                else
+                    thisObj->deleteProperty(exec, k + additionalArgs);
+            }
+            for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
+                thisObj->deleteProperty(exec, k - 1);
+        } else {
+            for (unsigned k = length - deleteCount; (int)k > begin; --k) {
+                if (JSValue* obj = getProperty(exec, thisObj, k + deleteCount - 1))
+                    thisObj->put(exec, k + additionalArgs - 1, obj);
+                else
+                    thisObj->deleteProperty(exec, k + additionalArgs - 1);
+            }
+        }
+    }
+    for (unsigned k = 0; k < additionalArgs; ++k)
+        thisObj->put(exec, k + begin, args.at(exec, k + 2));
+
+    putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
+    return result;
+}
+
+JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    // 15.4.4.13
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    unsigned nrArgs = args.size();
+    if (nrArgs) {
+        for (unsigned k = length; k > 0; --k) {
+            if (JSValue* v = getProperty(exec, thisObj, k - 1))
+                thisObj->put(exec, k + nrArgs - 1, v);
+            else
+                thisObj->deleteProperty(exec, k + nrArgs - 1);
+        }
+    }
+    for (unsigned k = 0; k < nrArgs; ++k)
+        thisObj->put(exec, k, args.at(exec, k));
+    JSValue* result = jsNumber(exec, length + nrArgs);
+    putProperty(exec, thisObj, exec->propertyNames().length, result);
+    return result;
+}
+
+JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args.at(exec, 0);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+    JSArray* resultArray = constructEmptyArray(exec);
+
+    unsigned filterIndex = 0;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+        PropertySlot slot(thisObj);
+
+        if (!thisObj->getPropertySlot(exec, k, slot))
+            continue;
+
+        JSValue* v = slot.getValue(exec, k);
+
+        ArgList eachArguments;
+
+        eachArguments.append(v);
+        eachArguments.append(jsNumber(exec, k));
+        eachArguments.append(thisObj);
+
+        JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
+
+        if (result->toBoolean(exec))
+            resultArray->put(exec, filterIndex++, v);
+    }
+    return resultArray;
+}
+
+JSValue* arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args.at(exec, 0);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+
+    JSArray* resultArray = constructEmptyArray(exec, length);
+
+    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+        PropertySlot slot(thisObj);
+        if (!thisObj->getPropertySlot(exec, k, slot))
+            continue;
+
+        JSValue* v = slot.getValue(exec, k);
+
+        ArgList eachArguments;
+
+        eachArguments.append(v);
+        eachArguments.append(jsNumber(exec, k));
+        eachArguments.append(thisObj);
+
+        JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
+        resultArray->put(exec, k, result);
+    }
+
+    return resultArray;
+}
+
+// Documentation for these three is available at:
+// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every
+// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
+// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
+
+JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args.at(exec, 0);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+
+    JSValue* result = jsBoolean(true);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+        PropertySlot slot(thisObj);
+
+        if (!thisObj->getPropertySlot(exec, k, slot))
+            continue;
+
+        ArgList eachArguments;
+
+        eachArguments.append(slot.getValue(exec, k));
+        eachArguments.append(jsNumber(exec, k));
+        eachArguments.append(thisObj);
+
+        bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
+
+        if (!predicateResult) {
+            result = jsBoolean(false);
+            break;
+        }
+    }
+
+    return result;
+}
+
+JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args.at(exec, 0);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+        PropertySlot slot(thisObj);
+        if (!thisObj->getPropertySlot(exec, k, slot))
+            continue;
+
+        ArgList eachArguments;
+        eachArguments.append(slot.getValue(exec, k));
+        eachArguments.append(jsNumber(exec, k));
+        eachArguments.append(thisObj);
+
+        call(exec, function, callType, callData, applyThis, eachArguments);
+    }
+    return jsUndefined();
+}
+
+JSValue* arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    JSValue* function = args.at(exec, 0);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+
+    JSValue* result = jsBoolean(false);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+        PropertySlot slot(thisObj);
+        if (!thisObj->getPropertySlot(exec, k, slot))
+            continue;
+
+        ArgList eachArguments;
+        eachArguments.append(slot.getValue(exec, k));
+        eachArguments.append(jsNumber(exec, k));
+        eachArguments.append(thisObj);
+
+        bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
+
+        if (predicateResult) {
+            result = jsBoolean(true);
+            break;
+        }
+    }
+    return result;
+}
+
+JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    // JavaScript 1.5 Extension by Mozilla
+    // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
+
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    unsigned index = 0;
+    double d = args.at(exec, 1)->toInteger(exec);
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    if (d < 0)
+        d += length;
+    if (d > 0) {
+        if (d > length)
+            index = length;
+        else
+            index = static_cast<unsigned>(d);
+    }
+
+    JSValue* searchElement = args.at(exec, 0);
+    for (; index < length; ++index) {
+        JSValue* e = getProperty(exec, thisObj, index);
+        if (!e)
+            continue;
+        if (strictEqual(searchElement, e))
+            return jsNumber(exec, index);
+    }
+
+    return jsNumber(exec, -1);
+}
+
+JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    // JavaScript 1.6 Extension by Mozilla
+    // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
+
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+    int index = length - 1;
+    double d = args.at(exec, 1)->toIntegerPreserveNaN(exec);
+
+    if (d < 0) {
+        d += length;
+        if (d < 0)
+            return jsNumber(exec, -1);
+    }
+    if (d < length)
+        index = static_cast<int>(d);
+
+    JSValue* searchElement = args.at(exec, 0);
+    for (; index >= 0; --index) {
+        JSValue* e = getProperty(exec, thisObj, index);
+        if (!e)
+            continue;
+        if (strictEqual(searchElement, e))
+            return jsNumber(exec, index);
+    }
+
+    return jsNumber(exec, -1);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ArrayPrototype.h b/JavaScriptCore/runtime/ArrayPrototype.h
new file mode 100644
index 0000000..33ce30b
--- /dev/null
+++ b/JavaScriptCore/runtime/ArrayPrototype.h
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  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
+ *
+ */
+
+#ifndef ArrayPrototype_h
+#define ArrayPrototype_h
+
+#include "JSArray.h"
+#include "lookup.h"
+
+namespace JSC {
+
+    class ArrayPrototype : public JSArray {
+    public:
+        explicit ArrayPrototype(PassRefPtr<StructureID>);
+
+        bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+    };
+
+} // namespace JSC
+
+#endif // ArrayPrototype_h
diff --git a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
new file mode 100644
index 0000000..536d09c
--- /dev/null
+++ b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -0,0 +1,55 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 BatchedTransitionOptimizer_h
+#define BatchedTransitionOptimizer_h
+
+#include <wtf/Noncopyable.h>
+#include "JSObject.h"
+
+namespace JSC {
+
+    class BatchedTransitionOptimizer : Noncopyable {
+    public:
+        BatchedTransitionOptimizer(JSObject* object)
+            : m_object(object)
+        {
+            if (!m_object->structureID()->isDictionary())
+                m_object->setStructureID(StructureID::toDictionaryTransition(m_object->structureID()));
+        }
+
+        ~BatchedTransitionOptimizer()
+        {
+            m_object->setStructureID(StructureID::fromDictionaryTransition(m_object->structureID()));
+        }
+
+    private:
+        JSObject* m_object;
+    };
+
+} // namespace JSC
+
+#endif // BatchedTransitionOptimizer_h
diff --git a/JavaScriptCore/runtime/BooleanConstructor.cpp b/JavaScriptCore/runtime/BooleanConstructor.cpp
new file mode 100644
index 0000000..46a6018
--- /dev/null
+++ b/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -0,0 +1,78 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "BooleanConstructor.h"
+
+#include "BooleanPrototype.h"
+#include "JSGlobalObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
+
+BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<StructureID> structure, BooleanPrototype* booleanPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, booleanPrototype->classInfo()->className))
+{
+    putDirectWithoutTransition(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
+
+    // no. of arguments for constructor
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
+}
+
+// ECMA 15.6.2
+JSObject* constructBoolean(ExecState* exec, const ArgList& args)
+{
+    BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
+    obj->setInternalValue(jsBoolean(args.at(exec, 0)->toBoolean(exec)));
+    return obj;
+}
+
+static JSObject* constructWithBooleanConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructBoolean(exec, args);
+}
+
+ConstructType BooleanConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithBooleanConstructor;
+    return ConstructTypeHost;
+}
+
+// ECMA 15.6.1
+static JSValue* callBooleanConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsBoolean(args.at(exec, 0)->toBoolean(exec));
+}
+
+CallType BooleanConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callBooleanConstructor;
+    return CallTypeHost;
+}
+
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue* immediateBooleanValue)
+{
+    BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
+    obj->setInternalValue(immediateBooleanValue);
+    return obj;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/BooleanConstructor.h b/JavaScriptCore/runtime/BooleanConstructor.h
new file mode 100644
index 0000000..3b1f1a0
--- /dev/null
+++ b/JavaScriptCore/runtime/BooleanConstructor.h
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef BooleanConstructor_h
+#define BooleanConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class BooleanPrototype;
+
+    class BooleanConstructor : public InternalFunction {
+    public:
+        BooleanConstructor(ExecState*, PassRefPtr<StructureID>, BooleanPrototype*);
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+    JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue*);
+    JSObject* constructBoolean(ExecState*, const ArgList&);
+
+} // namespace JSC
+
+#endif // BooleanConstructor_h
diff --git a/JavaScriptCore/runtime/BooleanObject.cpp b/JavaScriptCore/runtime/BooleanObject.cpp
new file mode 100644
index 0000000..2ebfb1b
--- /dev/null
+++ b/JavaScriptCore/runtime/BooleanObject.cpp
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "BooleanObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
+
+const ClassInfo BooleanObject::info = { "Boolean", 0, 0, 0 };
+
+BooleanObject::BooleanObject(PassRefPtr<StructureID> structure)
+    : JSWrapperObject(structure)
+{
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/BooleanObject.h b/JavaScriptCore/runtime/BooleanObject.h
new file mode 100644
index 0000000..5963b28
--- /dev/null
+++ b/JavaScriptCore/runtime/BooleanObject.h
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef BooleanObject_h
+#define BooleanObject_h
+
+#include "JSWrapperObject.h"
+
+namespace JSC {
+
+    class BooleanObject : public JSWrapperObject {
+    public:
+        explicit BooleanObject(PassRefPtr<StructureID>);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+    };
+
+    BooleanObject* asBooleanObject(JSValue*);
+
+    inline BooleanObject* asBooleanObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&BooleanObject::info));
+        return static_cast<BooleanObject*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // BooleanObject_h
diff --git a/JavaScriptCore/runtime/BooleanPrototype.cpp b/JavaScriptCore/runtime/BooleanPrototype.cpp
new file mode 100644
index 0000000..b47aeac
--- /dev/null
+++ b/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "BooleanPrototype.h"
+
+#include "Error.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
+
+// Functions
+static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+// ECMA 15.6.4
+
+BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+    : BooleanObject(structure)
+{
+    setInternalValue(jsBoolean(false));
+
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
+}
+
+
+// ------------------------------ Functions --------------------------
+
+// ECMA 15.6.4.2 + 15.6.4.3
+
+JSValue* booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (thisValue == jsBoolean(false))
+        return jsNontrivialString(exec, "false");
+
+    if (thisValue == jsBoolean(true))
+        return jsNontrivialString(exec, "true");
+
+    if (!thisValue->isObject(&BooleanObject::info))
+        return throwError(exec, TypeError);
+
+    if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
+        return jsNontrivialString(exec, "false");
+
+    ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true));
+    return jsNontrivialString(exec, "true");
+}
+
+JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (JSImmediate::isBoolean(thisValue))
+        return thisValue;
+
+    if (!thisValue->isObject(&BooleanObject::info))
+        return throwError(exec, TypeError);
+
+    return asBooleanObject(thisValue)->internalValue();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/BooleanPrototype.h b/JavaScriptCore/runtime/BooleanPrototype.h
new file mode 100644
index 0000000..484bb7d
--- /dev/null
+++ b/JavaScriptCore/runtime/BooleanPrototype.h
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef BooleanPrototype_h
+#define BooleanPrototype_h
+
+#include "BooleanObject.h"
+
+namespace JSC {
+
+    class BooleanPrototype : public BooleanObject {
+    public:
+        BooleanPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+    };
+
+} // namespace JSC
+
+#endif // BooleanPrototype_h
diff --git a/JavaScriptCore/runtime/CallData.cpp b/JavaScriptCore/runtime/CallData.cpp
new file mode 100644
index 0000000..572c495
--- /dev/null
+++ b/JavaScriptCore/runtime/CallData.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "CallData.h"
+
+#include "JSFunction.h"
+
+namespace JSC {
+
+JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args)
+{
+    if (callType == CallTypeHost)
+        return callData.native.function(exec, asObject(functionObject), thisValue, args);
+    ASSERT(callType == CallTypeJS);
+    // FIXME: Can this be done more efficiently using the callData?
+    return asFunction(functionObject)->call(exec, thisValue, args);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/CallData.h b/JavaScriptCore/runtime/CallData.h
new file mode 100644
index 0000000..5be011a
--- /dev/null
+++ b/JavaScriptCore/runtime/CallData.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 CallData_h
+#define CallData_h
+
+#include "JSImmediate.h"
+
+namespace JSC {
+
+    class ArgList;
+    class ExecState;
+    class FunctionBodyNode;
+    class JSObject;
+    class ScopeChainNode;
+
+    enum CallType {
+        CallTypeNone,
+        CallTypeHost,
+        CallTypeJS
+    };
+
+    typedef JSValue* (*NativeFunction)(ExecState*, JSObject*, JSValue* thisValue, const ArgList&);
+
+    union CallData {
+        struct {
+            NativeFunction function;
+        } native;
+        struct {
+            FunctionBodyNode* functionBody;
+            ScopeChainNode* scopeChain;
+        } js;
+    };
+
+    JSValue* call(ExecState*, JSValue* functionObject, CallType, const CallData&, JSValue* thisValue, const ArgList&);
+
+} // namespace JSC
+
+#endif // CallData_h
diff --git a/JavaScriptCore/runtime/ClassInfo.h b/JavaScriptCore/runtime/ClassInfo.h
new file mode 100644
index 0000000..979145e
--- /dev/null
+++ b/JavaScriptCore/runtime/ClassInfo.h
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ClassInfo_h
+#define ClassInfo_h
+
+#include "ExecState.h"
+
+namespace JSC {
+
+    struct HashEntry;
+    struct HashTable;
+
+    struct ClassInfo {
+        /**
+         * A string denoting the class name. Example: "Window".
+         */
+        const char* className;
+
+        /**
+         * Pointer to the class information of the base class.
+         * 0L if there is none.
+         */
+        const ClassInfo* parentClass;
+        /**
+         * Static hash-table of properties.
+         * For classes that can be used from multiple threads, it is accessed via a getter function that would typically return a pointer to thread-specific value.
+         */
+        const HashTable* propHashTable(ExecState* exec) const
+        {
+            if (classPropHashTableGetterFunction)
+                return classPropHashTableGetterFunction(exec);
+            return staticPropHashTable;
+        }
+
+        const HashTable* staticPropHashTable;
+        typedef const HashTable* (*ClassPropHashTableGetterFunction)(ExecState*);
+        const ClassPropHashTableGetterFunction classPropHashTableGetterFunction;
+    };
+
+} // namespace JSC
+
+#endif // ClassInfo_h
diff --git a/JavaScriptCore/runtime/CollectorHeapIterator.h b/JavaScriptCore/runtime/CollectorHeapIterator.h
new file mode 100644
index 0000000..c5e1d78
--- /dev/null
+++ b/JavaScriptCore/runtime/CollectorHeapIterator.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "collector.h"
+
+namespace JSC {
+
+    template <HeapType heapType> class CollectorHeapIterator {
+    public:
+        CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock);
+
+        bool operator!=(const CollectorHeapIterator<heapType>& other) { return m_block != other.m_block || m_cell != other.m_cell; }
+        CollectorHeapIterator<heapType>& operator++();
+        JSCell* operator*() const;
+    
+    private:
+        typedef typename HeapConstants<heapType>::Block Block;
+        typedef typename HeapConstants<heapType>::Cell Cell;
+
+        Block** m_block;
+        Block** m_endBlock;
+        Cell* m_cell;
+        Cell* m_endCell;
+    };
+
+    template <HeapType heapType> 
+    CollectorHeapIterator<heapType>::CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock)
+        : m_block(reinterpret_cast<Block**>(block))
+        , m_endBlock(reinterpret_cast<Block**>(endBlock))
+        , m_cell(m_block == m_endBlock ? 0 : (*m_block)->cells)
+        , m_endCell(m_block == m_endBlock ? 0 : (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock)
+    {
+        if (m_cell && m_cell->u.freeCell.zeroIfFree == 0)
+            ++*this;
+    }
+
+    template <HeapType heapType> 
+    CollectorHeapIterator<heapType>& CollectorHeapIterator<heapType>::operator++()
+    {
+        do {
+            for (++m_cell; m_cell != m_endCell; ++m_cell)
+                if (m_cell->u.freeCell.zeroIfFree != 0) {
+                    return *this;
+                }
+
+            if (++m_block != m_endBlock) {
+                m_cell = (*m_block)->cells;
+                m_endCell = (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock;
+            }
+        } while(m_block != m_endBlock);
+
+        m_cell = 0;
+        return *this;
+    }
+
+    template <HeapType heapType> 
+    JSCell* CollectorHeapIterator<heapType>::operator*() const
+    {
+        return reinterpret_cast<JSCell*>(m_cell);
+    }
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.cpp b/JavaScriptCore/runtime/CommonIdentifiers.cpp
new file mode 100644
index 0000000..fe0a830
--- /dev/null
+++ b/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "CommonIdentifiers.h"
+
+namespace JSC {
+
+const char* const nullCString = 0;
+
+#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
+
+CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
+    : nullIdentifier(globalData, nullCString)
+    , underscoreProto(globalData, "__proto__")
+    , thisIdentifier(globalData, "this")
+    JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
+{
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
new file mode 100644
index 0000000..1788c77
--- /dev/null
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (C) 2003,2007 Apple Computer, Inc
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef CommonIdentifiers_h
+#define CommonIdentifiers_h
+
+#include "identifier.h"
+#include <wtf/Noncopyable.h>
+
+// ArgList of property names, passed to a macro so we can do set them up various
+// ways without repeating the list.
+#define JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
+    macro(__defineGetter__) \
+    macro(__defineSetter__) \
+    macro(__lookupGetter__) \
+    macro(__lookupSetter__) \
+    macro(apply) \
+    macro(arguments) \
+    macro(call) \
+    macro(callee) \
+    macro(caller) \
+    macro(compile) \
+    macro(constructor) \
+    macro(eval) \
+    macro(exec) \
+    macro(fromCharCode) \
+    macro(global) \
+    macro(hasOwnProperty) \
+    macro(ignoreCase) \
+    macro(index) \
+    macro(input) \
+    macro(isPrototypeOf) \
+    macro(length) \
+    macro(message) \
+    macro(multiline) \
+    macro(name) \
+    macro(now) \
+    macro(parse) \
+    macro(propertyIsEnumerable) \
+    macro(prototype) \
+    macro(source) \
+    macro(test) \
+    macro(toExponential) \
+    macro(toFixed) \
+    macro(toLocaleString) \
+    macro(toPrecision) \
+    macro(toString) \
+    macro(UTC) \
+    macro(valueOf)
+
+namespace JSC {
+
+    class CommonIdentifiers : Noncopyable {
+    private:
+        CommonIdentifiers(JSGlobalData*);
+        friend class JSGlobalData;
+
+    public:
+        const Identifier nullIdentifier;
+        const Identifier underscoreProto;
+        const Identifier thisIdentifier;
+
+#define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name;
+        JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
+#undef JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL
+    };
+
+} // namespace JSC
+
+#endif // CommonIdentifiers_h
diff --git a/JavaScriptCore/runtime/ConstructData.cpp b/JavaScriptCore/runtime/ConstructData.cpp
new file mode 100644
index 0000000..88a8ef6
--- /dev/null
+++ b/JavaScriptCore/runtime/ConstructData.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ConstructData.h"
+
+#include "JSFunction.h"
+
+namespace JSC {
+
+JSObject* construct(ExecState* exec, JSValue* object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+{
+    if (constructType == ConstructTypeHost)
+        return constructData.native.function(exec, asObject(object), args);
+    ASSERT(constructType == ConstructTypeJS);
+    // FIXME: Can this be done more efficiently using the constructData?
+    return asFunction(object)->construct(exec, args);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ConstructData.h b/JavaScriptCore/runtime/ConstructData.h
new file mode 100644
index 0000000..3cc52a0
--- /dev/null
+++ b/JavaScriptCore/runtime/ConstructData.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 ConstructData_h
+#define ConstructData_h
+
+#include "JSImmediate.h" // temporary until JSValue* becomes a class we can forward-declare
+
+namespace JSC {
+
+    class ArgList;
+    class ExecState;
+    class FunctionBodyNode;
+    class JSObject;
+    class ScopeChainNode;
+
+    enum ConstructType {
+        ConstructTypeNone,
+        ConstructTypeHost,
+        ConstructTypeJS
+    };
+
+    typedef JSObject* (*NativeConstructor)(ExecState*, JSObject*, const ArgList&);
+
+    union ConstructData {
+        struct {
+            NativeConstructor function;
+        } native;
+        struct {
+            FunctionBodyNode* functionBody;
+            ScopeChainNode* scopeChain;
+        } js;
+    };
+
+    JSObject* construct(ExecState*, JSValue* constructor, ConstructType, const ConstructData&, const ArgList&);
+
+} // namespace JSC
+
+#endif // ConstructData_h
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
new file mode 100644
index 0000000..8339ff3
--- /dev/null
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -0,0 +1,175 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "DateConstructor.h"
+
+#include "DateInstance.h"
+#include "DateMath.h"
+#include "DatePrototype.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+#include <math.h>
+#include <time.h>
+#include <wtf/MathExtras.h>
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if HAVE(SYS_TIMEB_H)
+#include <sys/timeb.h>
+#endif
+
+namespace JSC {
+
+// TODO: MakeTime (15.9.11.1) etc. ?
+
+ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
+
+static JSValue* dateParse(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateNow(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateUTC(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+DateConstructor::DateConstructor(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure, DatePrototype* datePrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, datePrototype->classInfo()->className))
+{
+      putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
+
+      putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum);
+      putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
+      putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum);
+
+      putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 7), ReadOnly | DontEnum | DontDelete);
+}
+
+// ECMA 15.9.3
+JSObject* constructDate(ExecState* exec, const ArgList& args)
+{
+    int numArgs = args.size();
+
+    double value;
+
+    if (numArgs == 0) // new Date() ECMA 15.9.3.3
+        value = getCurrentUTCTime();
+    else if (numArgs == 1) {
+        if (args.at(exec, 0)->isObject(&DateInstance::info))
+            value = asDateInstance(args.at(exec, 0))->internalNumber();
+        else {
+            JSValue* primitive = args.at(exec, 0)->toPrimitive(exec);
+            if (primitive->isString())
+                value = parseDate(primitive->getString());
+            else
+                value = primitive->toNumber(exec);
+        }
+    } else {
+        if (isnan(args.at(exec, 0)->toNumber(exec))
+                || isnan(args.at(exec, 1)->toNumber(exec))
+                || (numArgs >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
+                || (numArgs >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
+                || (numArgs >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
+                || (numArgs >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
+                || (numArgs >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
+            value = NaN;
+        else {
+          GregorianDateTime t;
+          int year = args.at(exec, 0)->toInt32(exec);
+          t.year = (year >= 0 && year <= 99) ? year : year - 1900;
+          t.month = args.at(exec, 1)->toInt32(exec);
+          t.monthDay = (numArgs >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
+          t.hour = args.at(exec, 3)->toInt32(exec);
+          t.minute = args.at(exec, 4)->toInt32(exec);
+          t.second = args.at(exec, 5)->toInt32(exec);
+          t.isDST = -1;
+          double ms = (numArgs >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
+          value = gregorianDateTimeToMS(t, ms, false);
+        }
+    }
+
+    DateInstance* result = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure());
+    result->setInternalValue(jsNumber(exec, timeClip(value)));
+    return result;
+}
+    
+static JSObject* constructWithDateConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructDate(exec, args);
+}
+
+ConstructType DateConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithDateConstructor;
+    return ConstructTypeHost;
+}
+
+// ECMA 15.9.2
+static JSValue* callDate(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+{
+    time_t localTime = time(0);
+    tm localTM;
+    getLocalTime(&localTime, &localTM);
+    GregorianDateTime ts(localTM);
+    return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts, false));
+}
+
+CallType DateConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callDate;
+    return CallTypeHost;
+}
+
+static JSValue* dateParse(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, parseDate(args.at(exec, 0)->toString(exec)));
+}
+
+static JSValue* dateNow(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+{
+    return jsNumber(exec, getCurrentUTCTime());
+}
+
+static JSValue* dateUTC(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    int n = args.size();
+    if (isnan(args.at(exec, 0)->toNumber(exec))
+            || isnan(args.at(exec, 1)->toNumber(exec))
+            || (n >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
+            || (n >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
+            || (n >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
+            || (n >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
+            || (n >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    int year = args.at(exec, 0)->toInt32(exec);
+    t.year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.month = args.at(exec, 1)->toInt32(exec);
+    t.monthDay = (n >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
+    t.hour = args.at(exec, 3)->toInt32(exec);
+    t.minute = args.at(exec, 4)->toInt32(exec);
+    t.second = args.at(exec, 5)->toInt32(exec);
+    double ms = (n >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
+    return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/DateConstructor.h b/JavaScriptCore/runtime/DateConstructor.h
new file mode 100644
index 0000000..1279f82
--- /dev/null
+++ b/JavaScriptCore/runtime/DateConstructor.h
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef DateConstructor_h
+#define DateConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class DatePrototype;
+
+    class DateConstructor : public InternalFunction {
+    public:
+        DateConstructor(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure, DatePrototype*);
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+    JSObject* constructDate(ExecState*, const ArgList&);
+
+} // namespace JSC
+
+#endif // DateConstructor_h
diff --git a/JavaScriptCore/runtime/DateInstance.cpp b/JavaScriptCore/runtime/DateInstance.cpp
new file mode 100644
index 0000000..b38c6ef
--- /dev/null
+++ b/JavaScriptCore/runtime/DateInstance.cpp
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "DateInstance.h"
+
+#include "DateMath.h"
+#include <math.h>
+#include <wtf/MathExtras.h>
+
+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(PassRefPtr<StructureID> structure)
+    : JSWrapperObject(structure)
+    , m_cache(0)
+{
+}
+
+DateInstance::~DateInstance()
+{
+    delete m_cache;
+}
+
+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 (outputIsUTC) {
+        if (m_cache->m_gregorianDateTimeUTCCachedForMS != milli) {
+            JSC::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC);
+            m_cache->m_gregorianDateTimeUTCCachedForMS = milli;
+        }
+        t.copyFrom(m_cache->m_cachedGregorianDateTimeUTC);
+    } else {
+        if (m_cache->m_gregorianDateTimeCachedForMS != milli) {
+            JSC::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime);
+            m_cache->m_gregorianDateTimeCachedForMS = milli;
+        }
+        t.copyFrom(m_cache->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;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/DateInstance.h b/JavaScriptCore/runtime/DateInstance.h
new file mode 100644
index 0000000..98f4b64
--- /dev/null
+++ b/JavaScriptCore/runtime/DateInstance.h
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef DateInstance_h
+#define DateInstance_h
+
+#include "JSWrapperObject.h"
+
+namespace JSC {
+
+    struct GregorianDateTime;
+
+    class DateInstance : public JSWrapperObject {
+    public:
+        explicit DateInstance(PassRefPtr<StructureID>);
+        virtual ~DateInstance();
+
+        double internalNumber() const { return internalValue()->uncheckedGetNumber(); }
+
+        bool getTime(GregorianDateTime&, int& offset) const;
+        bool getUTCTime(GregorianDateTime&) const;
+        bool getTime(double& milliseconds, int& offset) const;
+        bool getUTCTime(double& milliseconds) const;
+
+        static const ClassInfo info;
+
+        void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&) const;
+
+    private:
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        using JSWrapperObject::internalValue;
+
+        struct Cache;
+        mutable Cache* m_cache;
+    };
+
+    DateInstance* asDateInstance(JSValue*);
+
+    inline DateInstance* asDateInstance(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&DateInstance::info));
+        return static_cast<DateInstance*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // DateInstance_h
diff --git a/JavaScriptCore/runtime/DateMath.cpp b/JavaScriptCore/runtime/DateMath.cpp
new file mode 100644
index 0000000..ec2a3f6
--- /dev/null
+++ b/JavaScriptCore/runtime/DateMath.cpp
@@ -0,0 +1,1046 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * 
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above.  If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "DateMath.h"
+
+#include "JSNumberCell.h"
+#include <math.h>
+#include <stdint.h>
+#include <time.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StringExtras.h>
+
+#if HAVE(ERRNO_H)
+#include <errno.h>
+#endif
+
+#if PLATFORM(DARWIN)
+#include <notify.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if HAVE(SYS_TIMEB_H)
+#include <sys/timeb.h>
+#endif
+
+using namespace WTF;
+
+namespace JSC {
+
+/* Constants */
+
+static const double minutesPerDay = 24.0 * 60.0;
+static const double secondsPerDay = 24.0 * 60.0 * 60.0;
+static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0;
+
+static const double usecPerSec = 1000000.0;
+
+static const double maxUnixTime = 2145859200.0; // 12/31/2037
+
+// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1.
+// First for non-leap years, then for leap years.
+static const int firstDayOfMonth[2][12] = {
+    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
+    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
+};
+
+static inline bool isLeapYear(int year)
+{
+    if (year % 4 != 0)
+        return false;
+    if (year % 400 == 0)
+        return true;
+    if (year % 100 == 0)
+        return false;
+    return true;
+}
+
+static inline int daysInYear(int year)
+{
+    return 365 + isLeapYear(year);
+}
+
+static inline double daysFrom1970ToYear(int year)
+{
+    // The Gregorian Calendar rules for leap years:
+    // Every fourth year is a leap year.  2004, 2008, and 2012 are leap years.
+    // However, every hundredth year is not a leap year.  1900 and 2100 are not leap years.
+    // Every four hundred years, there's a leap year after all.  2000 and 2400 are leap years.
+
+    static const int leapDaysBefore1971By4Rule = 1970 / 4;
+    static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100;
+    static const int leapDaysBefore1971By400Rule = 1970 / 400;
+
+    const double yearMinusOne = year - 1;
+    const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule;
+    const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule;
+    const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule;
+
+    return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule;
+}
+
+static inline double msToDays(double ms)
+{
+    return floor(ms / msPerDay);
+}
+
+static inline int msToYear(double ms)
+{
+    int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);
+    double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);
+    if (msFromApproxYearTo1970 > ms)
+        return approxYear - 1;
+    if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms)
+        return approxYear + 1;
+    return approxYear;
+}
+
+static inline int dayInYear(double ms, int year)
+{
+    return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
+}
+
+static inline double msToMilliseconds(double ms)
+{
+    double result = fmod(ms, msPerDay);
+    if (result < 0)
+        result += msPerDay;
+    return result;
+}
+
+// 0: Sunday, 1: Monday, etc.
+static inline int msToWeekDay(double ms)
+{
+    int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
+    if (wd < 0)
+        wd += 7;
+    return wd;
+}
+
+static inline int msToSeconds(double ms)
+{
+    double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
+    if (result < 0)
+        result += secondsPerMinute;
+    return static_cast<int>(result);
+}
+
+static inline int msToMinutes(double ms)
+{
+    double result = fmod(floor(ms / msPerMinute), minutesPerHour);
+    if (result < 0)
+        result += minutesPerHour;
+    return static_cast<int>(result);
+}
+
+static inline int msToHours(double ms)
+{
+    double result = fmod(floor(ms/msPerHour), hoursPerDay);
+    if (result < 0)
+        result += hoursPerDay;
+    return static_cast<int>(result);
+}
+
+static inline int monthFromDayInYear(int dayInYear, bool leapYear)
+{
+    const int d = dayInYear;
+    int step;
+
+    if (d < (step = 31))
+        return 0;
+    step += (leapYear ? 29 : 28);
+    if (d < step)
+        return 1;
+    if (d < (step += 31))
+        return 2;
+    if (d < (step += 30))
+        return 3;
+    if (d < (step += 31))
+        return 4;
+    if (d < (step += 30))
+        return 5;
+    if (d < (step += 31))
+        return 6;
+    if (d < (step += 31))
+        return 7;
+    if (d < (step += 30))
+        return 8;
+    if (d < (step += 31))
+        return 9;
+    if (d < (step += 30))
+        return 10;
+    return 11;
+}
+
+static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth)
+{
+    startDayOfThisMonth = startDayOfNextMonth;
+    startDayOfNextMonth += daysInThisMonth;
+    return (dayInYear <= startDayOfNextMonth);
+}
+
+static inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
+{
+    const int d = dayInYear;
+    int step;
+    int next = 30;
+
+    if (d <= next)
+        return d + 1;
+    const int daysInFeb = (leapYear ? 29 : 28);
+    if (checkMonth(d, step, next, daysInFeb))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    step = next;
+    return d - step;
+}
+
+static inline int monthToDayInYear(int month, bool isLeapYear)
+{
+    return firstDayOfMonth[isLeapYear][month];
+}
+
+static inline double timeToMS(double hour, double min, double sec, double ms)
+{
+    return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
+}
+
+static int dateToDayInYear(int year, int month, int day)
+{
+    year += month / 12;
+
+    month %= 12;
+    if (month < 0) {
+        month += 12;
+        --year;
+    }
+
+    int yearday = static_cast<int>(floor(daysFrom1970ToYear(year)));
+    int monthday = monthToDayInYear(month, isLeapYear(year));
+
+    return yearday + monthday + day - 1;
+}
+
+double getCurrentUTCTime()
+{
+    return floor(getCurrentUTCTimeWithMicroseconds());
+}
+
+#if PLATFORM(WIN_OS)
+
+static LARGE_INTEGER qpcFrequency;
+static bool syncedTime;
+
+static double highResUpTime()
+{
+    // We use QPC, but only after sanity checking its result, due to bugs:
+    // http://support.microsoft.com/kb/274323
+    // http://support.microsoft.com/kb/895980
+    // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)."
+
+    static LARGE_INTEGER qpcLast;
+    static DWORD tickCountLast;
+    static bool inited;
+
+    LARGE_INTEGER qpc;
+    QueryPerformanceCounter(&qpc);
+    DWORD tickCount = GetTickCount();
+
+    if (inited) {
+        __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart;
+        __int64 tickCountElapsed;
+        if (tickCount >= tickCountLast)
+            tickCountElapsed = (tickCount - tickCountLast);
+        else {
+#if COMPILER(MINGW)
+            __int64 tickCountLarge = tickCount + 0x100000000ULL;
+#else
+            __int64 tickCountLarge = tickCount + 0x100000000I64;
+#endif
+            tickCountElapsed = tickCountLarge - tickCountLast;
+        }
+
+        // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms.
+        // (500ms value is from http://support.microsoft.com/kb/274323)
+        __int64 diff = tickCountElapsed - qpcElapsed;
+        if (diff > 500 || diff < -500)
+            syncedTime = false;
+    } else
+        inited = true;
+
+    qpcLast = qpc;
+    tickCountLast = tickCount;
+
+    return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);;
+}
+
+static double lowResUTCTime()
+{
+    struct _timeb timebuffer;
+    _ftime(&timebuffer);
+    return timebuffer.time * msPerSecond + timebuffer.millitm;
+}
+
+static bool qpcAvailable()
+{
+    static bool available;
+    static bool checked;
+
+    if (checked)
+        return available;
+
+    available = QueryPerformanceFrequency(&qpcFrequency);
+    checked = true;
+    return available;
+}
+
+#endif
+
+double getCurrentUTCTimeWithMicroseconds()
+{
+#if PLATFORM(WIN_OS)
+    // Use a combination of ftime and QueryPerformanceCounter.
+    // ftime returns the information we want, but doesn't have sufficient resolution.
+    // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals.
+    // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter
+    // by itself, adding the delta to the saved ftime.  We periodically re-sync to correct for drift.
+    static bool started;
+    static double syncLowResUTCTime;
+    static double syncHighResUpTime;
+    static double lastUTCTime;
+
+    double lowResTime = lowResUTCTime();
+
+    if (!qpcAvailable())
+        return lowResTime;
+
+    double highResTime = highResUpTime();
+
+    if (!syncedTime) {
+        timeBeginPeriod(1); // increase time resolution around low-res time getter
+        syncLowResUTCTime = lowResTime = lowResUTCTime();
+        timeEndPeriod(1); // restore time resolution
+        syncHighResUpTime = highResTime;
+        syncedTime = true;
+    }
+
+    double highResElapsed = highResTime - syncHighResUpTime;
+    double utc = syncLowResUTCTime + highResElapsed;
+
+    // force a clock re-sync if we've drifted
+    double lowResElapsed = lowResTime - syncLowResUTCTime;
+    const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy
+    if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec)
+        syncedTime = false;
+
+    // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur)
+    const double backwardTimeLimit = 2000.0;
+    if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit)
+        return lastUTCTime;
+    lastUTCTime = utc;
+#else
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    double utc = tv.tv_sec * msPerSecond + tv.tv_usec / 1000.0;
+#endif
+    return utc;
+}
+
+void getLocalTime(const time_t* localTime, struct tm* localTM)
+{
+#if COMPILER(MSVC7) || COMPILER(MINGW)
+    *localTM = *localtime(localTime);
+#elif COMPILER(MSVC)
+    localtime_s(localTM, localTime);
+#else
+    localtime_r(localTime, localTM);
+#endif
+}
+
+// There is a hard limit at 2038 that we currently do not have a workaround
+// for (rdar://problem/5052975).
+static inline int maximumYearForDST()
+{
+    return 2037;
+}
+
+static inline int minimumYearForDST()
+{
+    // Because of the 2038 issue (see maximumYearForDST) if the current year is
+    // greater than the max year minus 27 (2010), we want to use the max year
+    // minus 27 instead, to ensure there is a range of 28 years that all years
+    // can map to.
+    return std::min(msToYear(getCurrentUTCTime()), maximumYearForDST() - 27) ;
+}
+
+/*
+ * Find an equivalent year for the one given, where equivalence is deterined by
+ * the two years having the same leapness and the first day of the year, falling
+ * on the same day of the week.
+ *
+ * This function returns a year between this current year and 2037, however this
+ * function will potentially return incorrect results if the current year is after
+ * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after
+ * 2100, (rdar://problem/5055038).
+ */
+int equivalentYearForDST(int year)
+{
+    // It is ok if the cached year is not the current year as long as the rules
+    // for DST did not change between the two years; if they did the app would need
+    // to be restarted.
+    static int minYear = minimumYearForDST();
+    int maxYear = maximumYearForDST();
+
+    int difference;
+    if (year > maxYear)
+        difference = minYear - year;
+    else if (year < minYear)
+        difference = maxYear - year;
+    else
+        return year;
+
+    int quotient = difference / 28;
+    int product = (quotient) * 28;
+
+    year += product;
+    ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast<int>(NaN)));
+    return year;
+}
+
+static int32_t calculateUTCOffset()
+{
+    tm localt;
+    memset(&localt, 0, sizeof(localt));
+ 
+    // get the difference between this time zone and UTC on Jan 01, 2000 12:00:00 AM
+    localt.tm_mday = 1;
+    localt.tm_year = 100;
+    time_t utcOffset = 946684800 - mktime(&localt);
+
+    return static_cast<int32_t>(utcOffset * 1000);
+}
+
+#if PLATFORM(DARWIN)
+static int32_t s_cachedUTCOffset; // In milliseconds. An assumption here is that access to an int32_t variable is atomic on platforms that take this code path.
+static bool s_haveCachedUTCOffset;
+static int s_notificationToken;
+#endif
+
+/*
+ * Get the difference in milliseconds between this time zone and UTC (GMT)
+ * NOT including DST.
+ */
+double getUTCOffset()
+{
+#if PLATFORM(DARWIN)
+    if (s_haveCachedUTCOffset) {
+        int notified;
+        uint32_t status = notify_check(s_notificationToken, &notified);
+        if (status == NOTIFY_STATUS_OK && !notified)
+            return s_cachedUTCOffset;
+    }
+#endif
+
+    int32_t utcOffset = calculateUTCOffset();
+
+#if PLATFORM(DARWIN)
+    // Theoretically, it is possible that several threads will be executing this code at once, in which case we will have a race condition,
+    // and a newer value may be overwritten. In practice, time zones don't change that often.
+    s_cachedUTCOffset = utcOffset;
+#endif
+
+    return utcOffset;
+}
+
+/*
+ * Get the DST offset for the time passed in.  Takes
+ * seconds (not milliseconds) and cannot handle dates before 1970
+ * on some OS'
+ */
+static double getDSTOffsetSimple(double localTimeSeconds, double utcOffset)
+{
+    if (localTimeSeconds > maxUnixTime)
+        localTimeSeconds = maxUnixTime;
+    else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
+        localTimeSeconds += secondsPerDay;
+
+    //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
+    double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset;
+
+    // Offset from UTC but doesn't include DST obviously
+    int offsetHour =  msToHours(offsetTime);
+    int offsetMinute =  msToMinutes(offsetTime);
+
+    // FIXME: time_t has a potential problem in 2038
+    time_t localTime = static_cast<time_t>(localTimeSeconds);
+
+    tm localTM;
+    getLocalTime(&localTime, &localTM);
+
+    double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60);
+
+    if (diff < 0)
+        diff += secondsPerDay;
+
+    return (diff * msPerSecond);
+}
+
+// Get the DST offset, given a time in UTC
+static double getDSTOffset(double ms, double utcOffset)
+{
+    // On Mac OS X, the call to localtime (see getDSTOffsetSimple) will return historically accurate
+    // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
+    // standard explicitly dictates that historical information should not be considered when
+    // determining DST. For this reason we shift away from years that localtime can handle but would
+    // return historically accurate information.
+    int year = msToYear(ms);
+    int equivalentYear = equivalentYearForDST(year);
+    if (year != equivalentYear) {
+        bool leapYear = isLeapYear(year);
+        int dayInYearLocal = dayInYear(ms, year);
+        int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
+        int month = monthFromDayInYear(dayInYearLocal, leapYear);
+        int day = dateToDayInYear(equivalentYear, month, dayInMonth);
+        ms = (day * msPerDay) + msToMilliseconds(ms);
+    }
+
+    return getDSTOffsetSimple(ms / msPerSecond, utcOffset);
+}
+
+double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+{
+    int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay);
+    double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
+    double result = (day * msPerDay) + ms;
+
+    if (!inputIsUTC) { // convert to UTC
+        double utcOffset = getUTCOffset();
+        result -= utcOffset;
+        result -= getDSTOffset(result, utcOffset);
+    }
+
+    return result;
+}
+
+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
+        dstOff = getDSTOffset(ms, utcOff);
+        ms += dstOff + utcOff;
+    }
+
+    const int year = msToYear(ms);
+    tm.second   =  msToSeconds(ms);
+    tm.minute   =  msToMinutes(ms);
+    tm.hour     =  msToHours(ms);
+    tm.weekDay  =  msToWeekDay(ms);
+    tm.yearDay  =  dayInYear(ms, year);
+    tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
+    tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));
+    tm.year     =  year - 1900;
+    tm.isDST    =  dstOff != 0.0;
+
+    tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond);
+    tm.timeZone = NULL;
+}
+
+void initDateMath()
+{
+#ifndef NDEBUG
+    static bool alreadyInitialized;
+    ASSERT(!alreadyInitialized++);
+#endif
+
+    equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
+#if PLATFORM(DARWIN)
+    // Register for a notification whenever the time zone changes.
+    uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);
+    if (status == NOTIFY_STATUS_OK) {
+        s_cachedUTCOffset = calculateUTCOffset();
+        s_haveCachedUTCOffset = true;
+    }
+#endif
+}
+
+static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
+{
+    double days = (day - 32075)
+        + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
+        + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
+        - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4)
+        - 2440588;
+    return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second;
+}
+
+// We follow the recommendation of RFC 2822 to consider all
+// obsolete time zones not listed here equivalent to "-0000".
+static const struct KnownZone {
+#if !PLATFORM(WIN_OS)
+    const
+#endif
+        char tzName[4];
+    int tzOffset;
+} known_zones[] = {
+    { "UT", 0 },
+    { "GMT", 0 },
+    { "EST", -300 },
+    { "EDT", -240 },
+    { "CST", -360 },
+    { "CDT", -300 },
+    { "MST", -420 },
+    { "MDT", -360 },
+    { "PST", -480 },
+    { "PDT", -420 }
+};
+
+inline static void skipSpacesAndComments(const char*& s)
+{
+    int nesting = 0;
+    char ch;
+    while ((ch = *s)) {
+        if (!isASCIISpace(ch)) {
+            if (ch == '(')
+                nesting++;
+            else if (ch == ')' && nesting > 0)
+                nesting--;
+            else if (nesting == 0)
+                break;
+        }
+        s++;
+    }
+}
+
+// returns 0-11 (Jan-Dec); -1 on failure
+static int findMonth(const char* monthStr)
+{
+    ASSERT(monthStr);
+    char needle[4];
+    for (int i = 0; i < 3; ++i) {
+        if (!*monthStr)
+            return -1;
+        needle[i] = static_cast<char>(toASCIILower(*monthStr++));
+    }
+    needle[3] = '\0';
+    const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec";
+    const char *str = strstr(haystack, needle);
+    if (str) {
+        int position = static_cast<int>(str - haystack);
+        if (position % 3 == 0)
+            return position / 3;
+    }
+    return -1;
+}
+
+double parseDate(const UString &date)
+{
+    // This parses a date in the form:
+    //     Tuesday, 09-Nov-99 23:12:40 GMT
+    // or
+    //     Sat, 01-Jan-2000 08:00:00 GMT
+    // or
+    //     Sat, 01 Jan 2000 08:00:00 GMT
+    // or
+    //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)
+    // ### non RFC formats, added for Javascript:
+    //     [Wednesday] January 09 1999 23:12:40 GMT
+    //     [Wednesday] January 09 23:12:40 GMT 1999
+    //
+    // We ignore the weekday.
+
+    CString dateCString = date.UTF8String();
+    const char *dateString = dateCString.c_str();
+     
+    // Skip leading space
+    skipSpacesAndComments(dateString);
+
+    long month = -1;
+    const char *wordStart = dateString;
+    // Check contents of first words if not number
+    while (*dateString && !isASCIIDigit(*dateString)) {
+        if (isASCIISpace(*dateString) || *dateString == '(') {
+            if (dateString - wordStart >= 3)
+                month = findMonth(wordStart);
+            skipSpacesAndComments(dateString);
+            wordStart = dateString;
+        } else
+           dateString++;
+    }
+
+    // Missing delimiter between month and day (like "January29")?
+    if (month == -1 && wordStart != dateString)
+        month = findMonth(wordStart);
+
+    skipSpacesAndComments(dateString);
+
+    if (!*dateString)
+        return NaN;
+
+    // ' 09-Nov-99 23:12:40 GMT'
+    char *newPosStr;
+    errno = 0;
+    long day = strtol(dateString, &newPosStr, 10);
+    if (errno)
+        return NaN;
+    dateString = newPosStr;
+
+    if (!*dateString)
+        return NaN;
+
+    if (day < 0)
+        return NaN;
+
+    long year = 0;
+    if (day > 31) {
+        // ### where is the boundary and what happens below?
+        if (*dateString != '/')
+            return NaN;
+        // looks like a YYYY/MM/DD date
+        if (!*++dateString)
+            return NaN;
+        year = day;
+        month = strtol(dateString, &newPosStr, 10) - 1;
+        if (errno)
+            return NaN;
+        dateString = newPosStr;
+        if (*dateString++ != '/' || !*dateString)
+            return NaN;
+        day = strtol(dateString, &newPosStr, 10);
+        if (errno)
+            return NaN;
+        dateString = newPosStr;
+    } else if (*dateString == '/' && month == -1) {
+        dateString++;
+        // This looks like a MM/DD/YYYY date, not an RFC date.
+        month = day - 1; // 0-based
+        day = strtol(dateString, &newPosStr, 10);
+        if (errno)
+            return NaN;
+        if (day < 1 || day > 31)
+            return NaN;
+        dateString = newPosStr;
+        if (*dateString == '/')
+            dateString++;
+        if (!*dateString)
+            return NaN;
+     } else {
+        if (*dateString == '-')
+            dateString++;
+
+        skipSpacesAndComments(dateString);
+
+        if (*dateString == ',')
+            dateString++;
+
+        if (month == -1) { // not found yet
+            month = findMonth(dateString);
+            if (month == -1)
+                return NaN;
+
+            while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))
+                dateString++;
+
+            if (!*dateString)
+                return NaN;
+
+            // '-99 23:12:40 GMT'
+            if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))
+                return NaN;
+            dateString++;
+        }
+    }
+
+    if (month < 0 || month > 11)
+        return NaN;
+
+    // '99 23:12:40 GMT'
+    if (year <= 0 && *dateString) {
+        year = strtol(dateString, &newPosStr, 10);
+        if (errno)
+            return NaN;
+    }
+    
+    // Don't fail if the time is missing.
+    long hour = 0;
+    long minute = 0;
+    long second = 0;
+    if (!*newPosStr)
+        dateString = newPosStr;
+    else {
+        // ' 23:12:40 GMT'
+        if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
+            if (*newPosStr != ':')
+                return NaN;
+            // There was no year; the number was the hour.
+            year = -1;
+        } else {
+            // in the normal case (we parsed the year), advance to the next number
+            dateString = ++newPosStr;
+            skipSpacesAndComments(dateString);
+        }
+
+        hour = strtol(dateString, &newPosStr, 10);
+        // Do not check for errno here since we want to continue
+        // even if errno was set becasue we are still looking
+        // for the timezone!
+
+        // Read a number? If not, this might be a timezone name.
+        if (newPosStr != dateString) {
+            dateString = newPosStr;
+
+            if (hour < 0 || hour > 23)
+                return NaN;
+
+            if (!*dateString)
+                return NaN;
+
+            // ':12:40 GMT'
+            if (*dateString++ != ':')
+                return NaN;
+
+            minute = strtol(dateString, &newPosStr, 10);
+            if (errno)
+                return NaN;
+            dateString = newPosStr;
+
+            if (minute < 0 || minute > 59)
+                return NaN;
+
+            // ':40 GMT'
+            if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
+                return NaN;
+
+            // seconds are optional in rfc822 + rfc2822
+            if (*dateString ==':') {
+                dateString++;
+
+                second = strtol(dateString, &newPosStr, 10);
+                if (errno)
+                    return NaN;
+                dateString = newPosStr;
+            
+                if (second < 0 || second > 59)
+                    return NaN;
+            }
+
+            skipSpacesAndComments(dateString);
+
+            if (strncasecmp(dateString, "AM", 2) == 0) {
+                if (hour > 12)
+                    return NaN;
+                if (hour == 12)
+                    hour = 0;
+                dateString += 2;
+                skipSpacesAndComments(dateString);
+            } else if (strncasecmp(dateString, "PM", 2) == 0) {
+                if (hour > 12)
+                    return NaN;
+                if (hour != 12)
+                    hour += 12;
+                dateString += 2;
+                skipSpacesAndComments(dateString);
+            }
+        }
+    }
+
+    bool haveTZ = false;
+    int offset = 0;
+
+    // Don't fail if the time zone is missing. 
+    // Some websites omit the time zone (4275206).
+    if (*dateString) {
+        if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {
+            dateString += 3;
+            haveTZ = true;
+        }
+
+        if (*dateString == '+' || *dateString == '-') {
+            long o = strtol(dateString, &newPosStr, 10);
+            if (errno)
+                return NaN;
+            dateString = newPosStr;
+
+            if (o < -9959 || o > 9959)
+                return NaN;
+
+            int sgn = (o < 0) ? -1 : 1;
+            o = abs(o);
+            if (*dateString != ':') {
+                offset = ((o / 100) * 60 + (o % 100)) * sgn;
+            } else { // GMT+05:00
+                long o2 = strtol(dateString, &newPosStr, 10);
+                if (errno)
+                    return NaN;
+                dateString = newPosStr;
+                offset = (o * 60 + o2) * sgn;
+            }
+            haveTZ = true;
+        } else {
+            for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) {
+                if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
+                    offset = known_zones[i].tzOffset;
+                    dateString += strlen(known_zones[i].tzName);
+                    haveTZ = true;
+                    break;
+                }
+            }
+        }
+    }
+
+    skipSpacesAndComments(dateString);
+
+    if (*dateString && year == -1) {
+        year = strtol(dateString, &newPosStr, 10);
+        if (errno)
+            return NaN;
+        dateString = newPosStr;
+    }
+     
+    skipSpacesAndComments(dateString);
+     
+    // Trailing garbage
+    if (*dateString)
+        return NaN;
+
+    // Y2K: Handle 2 digit years.
+    if (year >= 0 && year < 100) {
+        if (year < 50)
+            year += 2000;
+        else
+            year += 1900;
+    }
+
+    // fall back to local timezone
+    if (!haveTZ) {
+        GregorianDateTime t;
+        t.monthDay = day;
+        t.month = month;
+        t.year = year - 1900;
+        t.isDST = -1;
+        t.second = second;
+        t.minute = minute;
+        t.hour = hour;
+
+        // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
+        return gregorianDateTimeToMS(t, 0, false);
+    }
+
+    return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
+}
+
+double timeClip(double t)
+{
+    if (!isfinite(t))
+        return NaN;
+    if (fabs(t) > 8.64E15)
+        return NaN;
+    return trunc(t);
+}
+
+UString formatDate(const GregorianDateTime &t)
+{
+    char buffer[100];
+    snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
+        weekdayName[(t.weekDay + 6) % 7],
+        monthName[t.month], t.monthDay, t.year + 1900);
+    return buffer;
+}
+
+UString formatDateUTCVariant(const GregorianDateTime &t)
+{
+    char buffer[100];
+    snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
+        weekdayName[(t.weekDay + 6) % 7],
+        t.monthDay, monthName[t.month], t.year + 1900);
+    return buffer;
+}
+
+UString formatTime(const GregorianDateTime &t, bool utc)
+{
+    char buffer[100];
+    if (utc) {
+        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
+    } else {
+        int offset = abs(gmtoffset(t));
+        char tzname[70];
+        struct tm gtm = t;
+        strftime(tzname, sizeof(tzname), "%Z", &gtm);
+
+        if (tzname[0]) {
+            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
+                t.hour, t.minute, t.second,
+                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, tzname);
+        } else {
+            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
+                t.hour, t.minute, t.second,
+                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
+        }
+    }
+    return UString(buffer);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/DateMath.h b/JavaScriptCore/runtime/DateMath.h
new file mode 100644
index 0000000..ab939a7
--- /dev/null
+++ b/JavaScriptCore/runtime/DateMath.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef DateMath_h
+#define DateMath_h
+
+#include <time.h>
+#include <string.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class UString;
+struct GregorianDateTime;
+
+void initDateMath();
+void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
+double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
+double getUTCOffset();
+int equivalentYearForDST(int year);
+double getCurrentUTCTime();
+double getCurrentUTCTimeWithMicroseconds();
+void getLocalTime(const time_t*, tm*);
+
+// Not really math related, but this is currently the only shared place to put these.  
+double parseDate(const UString&);
+double timeClip(double);
+UString formatDate(const GregorianDateTime&);
+UString formatDateUTCVariant(const GregorianDateTime&);
+UString formatTime(const GregorianDateTime&, bool inputIsUTC);
+
+
+const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+const double hoursPerDay = 24.0;
+const double minutesPerHour = 60.0;
+const double secondsPerHour = 60.0 * 60.0;
+const double secondsPerMinute = 60.0;
+const double msPerSecond = 1000.0;
+const double msPerMinute = 60.0 * 1000.0;
+const double msPerHour = 60.0 * 60.0 * 1000.0;
+const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
+
+// Intentionally overridding the default tm of the system
+// Tee members of tm differ on various operating systems.
+struct GregorianDateTime : Noncopyable {
+    GregorianDateTime()
+        : second(0)
+        , minute(0)
+        , hour(0)
+        , weekDay(0)
+        , monthDay(0)
+        , yearDay(0)
+        , month(0)
+        , year(0)
+        , isDST(0)
+        , utcOffset(0)
+        , timeZone(0)
+    {
+    }
+
+    ~GregorianDateTime()
+    {
+        delete [] timeZone;
+    }
+
+    GregorianDateTime(const tm& inTm)
+        : second(inTm.tm_sec)
+        , minute(inTm.tm_min)
+        , hour(inTm.tm_hour)
+        , weekDay(inTm.tm_wday)
+        , monthDay(inTm.tm_mday)
+        , yearDay(inTm.tm_yday)
+        , month(inTm.tm_mon)
+        , year(inTm.tm_year)
+        , isDST(inTm.tm_isdst)
+    {
+#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS)
+        utcOffset = static_cast<int>(inTm.tm_gmtoff);
+
+        int inZoneSize = strlen(inTm.tm_zone) + 1;
+        timeZone = new char[inZoneSize];
+        strncpy(timeZone, inTm.tm_zone, inZoneSize);
+#else
+        utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0));
+        timeZone = 0;
+#endif
+    }
+
+    operator tm() const
+    {
+        tm ret;
+        memset(&ret, 0, sizeof(ret));
+
+        ret.tm_sec   =  second;
+        ret.tm_min   =  minute;
+        ret.tm_hour  =  hour;
+        ret.tm_wday  =  weekDay;
+        ret.tm_mday  =  monthDay;
+        ret.tm_yday  =  yearDay;
+        ret.tm_mon   =  month;
+        ret.tm_year  =  year;
+        ret.tm_isdst =  isDST;
+
+#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS)
+        ret.tm_gmtoff = static_cast<long>(utcOffset);
+        ret.tm_zone = timeZone;
+#endif
+
+        return ret;
+    }
+
+    void copyFrom(const GregorianDateTime& rhs)
+    {
+        second = rhs.second;
+        minute = rhs.minute;
+        hour = rhs.hour;
+        weekDay = rhs.weekDay;
+        monthDay = rhs.monthDay;
+        yearDay = rhs.yearDay;
+        month = rhs.month;
+        year = rhs.year;
+        isDST = rhs.isDST;
+        utcOffset = rhs.utcOffset;
+        if (rhs.timeZone) {
+            int inZoneSize = strlen(rhs.timeZone) + 1;
+            timeZone = new char[inZoneSize];
+            strncpy(timeZone, rhs.timeZone, inZoneSize);
+        } else
+            timeZone = 0;
+    }
+
+    int second;
+    int minute;
+    int hour;
+    int weekDay;
+    int monthDay;
+    int yearDay;
+    int month;
+    int year;
+    int isDST;
+    int utcOffset;
+    char* timeZone;
+};
+
+static inline int gmtoffset(const GregorianDateTime& t)
+{
+    return t.utcOffset;
+}
+
+} // namespace JSC
+
+#endif // DateMath_h
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
new file mode 100644
index 0000000..a3e792e
--- /dev/null
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -0,0 +1,1056 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "DatePrototype.h"
+
+#include "DateMath.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "DateInstance.h"
+#include <float.h>
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <time.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StringExtras.h>
+#include <wtf/UnusedParam.h>
+
+#if HAVE(SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if HAVE(SYS_TIMEB_H)
+#include <sys/timeb.h>
+#endif
+
+#if PLATFORM(MAC)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+using namespace WTF;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
+
+static JSValue* dateProtoFuncGetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetDay(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetTime(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncGetYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetTime(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncSetYear(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToDateString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToGMTString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToTimeString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncToUTCString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* dateProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "DatePrototype.lut.h"
+
+namespace JSC {
+
+#if PLATFORM(MAC)
+
+static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateFormatterStyle defaultStyle)
+{
+    if (string == "short")
+        return kCFDateFormatterShortStyle;
+    if (string == "medium")
+        return kCFDateFormatterMediumStyle;
+    if (string == "long")
+        return kCFDateFormatterLongStyle;
+    if (string == "full")
+        return kCFDateFormatterFullStyle;
+    return defaultStyle;
+}
+
+static UString formatLocaleDate(ExecState* exec, double time, bool includeDate, bool includeTime, const ArgList& args)
+{
+    CFDateFormatterStyle dateStyle = (includeDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+    CFDateFormatterStyle timeStyle = (includeTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+
+    bool useCustomFormat = false;
+    UString customFormatString;
+
+    UString arg0String = args.at(exec, 0)->toString(exec);
+    if (arg0String == "custom" && !args.at(exec, 1)->isUndefined()) {
+        useCustomFormat = true;
+        customFormatString = args.at(exec, 1)->toString(exec);
+    } else if (includeDate && includeTime && !args.at(exec, 1)->isUndefined()) {
+        dateStyle = styleFromArgString(arg0String, dateStyle);
+        timeStyle = styleFromArgString(args.at(exec, 1)->toString(exec), timeStyle);
+    } else if (includeDate && !args.at(exec, 0)->isUndefined())
+        dateStyle = styleFromArgString(arg0String, dateStyle);
+    else if (includeTime && !args.at(exec, 0)->isUndefined())
+        timeStyle = styleFromArgString(arg0String, timeStyle);
+
+    CFLocaleRef locale = CFLocaleCopyCurrent();
+    CFDateFormatterRef formatter = CFDateFormatterCreate(0, locale, dateStyle, timeStyle);
+    CFRelease(locale);
+
+    if (useCustomFormat) {
+        CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, (UniChar *)customFormatString.data(), customFormatString.size());
+        CFDateFormatterSetFormat(formatter, customFormatCFString);
+        CFRelease(customFormatCFString);
+    }
+
+    CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, time - kCFAbsoluteTimeIntervalSince1970);
+
+    CFRelease(formatter);
+
+    // We truncate the string returned from CFDateFormatter if it's absurdly long (> 200 characters).
+    // That's not great error handling, but it just won't happen so it doesn't matter.
+    UChar buffer[200];
+    const size_t bufferLength = sizeof(buffer) / sizeof(buffer[0]);
+    size_t length = CFStringGetLength(string);
+    ASSERT(length <= bufferLength);
+    if (length > bufferLength)
+        length = bufferLength;
+    CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast<UniChar *>(buffer));
+
+    CFRelease(string);
+
+    return UString(buffer, length);
+}
+
+#else
+
+enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
+ 
+static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
+{
+    static const char* formatStrings[] = {"%#c", "%#x", "%X"};
+ 
+    // Offset year if needed
+    struct tm localTM = gdt;
+    int year = gdt.year + 1900;
+    bool yearNeedsOffset = year < 1900 || year > 2038;
+    if (yearNeedsOffset)
+        localTM.tm_year = equivalentYearForDST(year) - 1900;
+ 
+    // Do the formatting
+    const int bufsize = 128;
+    char timebuffer[bufsize];
+    size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM);
+ 
+    if (ret == 0)
+        return jsEmptyString(exec);
+ 
+    // Copy original into the buffer
+    if (yearNeedsOffset && format != LocaleTime) {
+        static const int yearLen = 5;   // FIXME will be a problem in the year 10,000
+        char yearString[yearLen];
+ 
+        snprintf(yearString, yearLen, "%d", localTM.tm_year + 1900);
+        char* yearLocation = strstr(timebuffer, yearString);
+        snprintf(yearString, yearLen, "%d", year);
+ 
+        strncpy(yearLocation, yearString, yearLen - 1);
+    }
+ 
+    return jsNontrivialString(exec, timebuffer);
+}
+
+#endif // PLATFORM(WIN_OS)
+
+// Converts a list of arguments sent to a Date member function into milliseconds, updating
+// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
+//
+// Format of member function: f([hour,] [min,] [sec,] [ms])
+static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, int maxArgs, double* ms, GregorianDateTime* t)
+{
+    double milliseconds = 0;
+    bool ok = true;
+    int idx = 0;
+    int numArgs = args.size();
+    
+    // JS allows extra trailing arguments -- ignore them
+    if (numArgs > maxArgs)
+        numArgs = maxArgs;
+
+    // hours
+    if (maxArgs >= 4 && idx < numArgs) {
+        t->hour = 0;
+        milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerHour;
+    }
+
+    // minutes
+    if (maxArgs >= 3 && idx < numArgs && ok) {
+        t->minute = 0;
+        milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerMinute;
+    }
+    
+    // seconds
+    if (maxArgs >= 2 && idx < numArgs && ok) {
+        t->second = 0;
+        milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerSecond;
+    }
+    
+    if (!ok)
+        return false;
+        
+    // milliseconds
+    if (idx < numArgs) {
+        double millis = args.at(exec, idx)->toNumber(exec);
+        ok = isfinite(millis);
+        milliseconds += millis;
+    } else
+        milliseconds += *ms;
+    
+    *ms = milliseconds;
+    return ok;
+}
+
+// Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating
+// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
+//
+// Format of member function: f([years,] [months,] [days])
+static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList& args, int maxArgs, double *ms, GregorianDateTime *t)
+{
+    int idx = 0;
+    bool ok = true;
+    int numArgs = args.size();
+  
+    // JS allows extra trailing arguments -- ignore them
+    if (numArgs > maxArgs)
+        numArgs = maxArgs;
+  
+    // years
+    if (maxArgs >= 3 && idx < numArgs)
+        t->year = args.at(exec, idx++)->toInt32(exec, ok) - 1900;
+    
+    // months
+    if (maxArgs >= 2 && idx < numArgs && ok)   
+        t->month = args.at(exec, idx++)->toInt32(exec, ok);
+    
+    // days
+    if (idx < numArgs && ok) {   
+        t->monthDay = 0;
+        *ms += args.at(exec, idx)->toInt32(exec, ok) * msPerDay;
+    }
+    
+    return ok;
+}
+
+const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState::dateTable};
+
+/* Source for DatePrototype.lut.h
+   FIXME: We could use templates to simplify the UTC variants.
+@begin dateTable
+  toString              dateProtoFuncToString                DontEnum|Function       0
+  toUTCString           dateProtoFuncToUTCString             DontEnum|Function       0
+  toDateString          dateProtoFuncToDateString            DontEnum|Function       0
+  toTimeString          dateProtoFuncToTimeString            DontEnum|Function       0
+  toLocaleString        dateProtoFuncToLocaleString          DontEnum|Function       0
+  toLocaleDateString    dateProtoFuncToLocaleDateString      DontEnum|Function       0
+  toLocaleTimeString    dateProtoFuncToLocaleTimeString      DontEnum|Function       0
+  valueOf               dateProtoFuncValueOf                 DontEnum|Function       0
+  getTime               dateProtoFuncGetTime                 DontEnum|Function       0
+  getFullYear           dateProtoFuncGetFullYear             DontEnum|Function       0
+  getUTCFullYear        dateProtoFuncGetUTCFullYear          DontEnum|Function       0
+  toGMTString           dateProtoFuncToGMTString             DontEnum|Function       0
+  getMonth              dateProtoFuncGetMonth                DontEnum|Function       0
+  getUTCMonth           dateProtoFuncGetUTCMonth             DontEnum|Function       0
+  getDate               dateProtoFuncGetDate                 DontEnum|Function       0
+  getUTCDate            dateProtoFuncGetUTCDate              DontEnum|Function       0
+  getDay                dateProtoFuncGetDay                  DontEnum|Function       0
+  getUTCDay             dateProtoFuncGetUTCDay               DontEnum|Function       0
+  getHours              dateProtoFuncGetHours                DontEnum|Function       0
+  getUTCHours           dateProtoFuncGetUTCHours             DontEnum|Function       0
+  getMinutes            dateProtoFuncGetMinutes              DontEnum|Function       0
+  getUTCMinutes         dateProtoFuncGetUTCMinutes           DontEnum|Function       0
+  getSeconds            dateProtoFuncGetSeconds              DontEnum|Function       0
+  getUTCSeconds         dateProtoFuncGetUTCSeconds           DontEnum|Function       0
+  getMilliseconds       dateProtoFuncGetMilliSeconds         DontEnum|Function       0
+  getUTCMilliseconds    dateProtoFuncGetUTCMilliseconds      DontEnum|Function       0
+  getTimezoneOffset     dateProtoFuncGetTimezoneOffset       DontEnum|Function       0
+  setTime               dateProtoFuncSetTime                 DontEnum|Function       1
+  setMilliseconds       dateProtoFuncSetMilliSeconds         DontEnum|Function       1
+  setUTCMilliseconds    dateProtoFuncSetUTCMilliseconds      DontEnum|Function       1
+  setSeconds            dateProtoFuncSetSeconds              DontEnum|Function       2
+  setUTCSeconds         dateProtoFuncSetUTCSeconds           DontEnum|Function       2
+  setMinutes            dateProtoFuncSetMinutes              DontEnum|Function       3
+  setUTCMinutes         dateProtoFuncSetUTCMinutes           DontEnum|Function       3
+  setHours              dateProtoFuncSetHours                DontEnum|Function       4
+  setUTCHours           dateProtoFuncSetUTCHours             DontEnum|Function       4
+  setDate               dateProtoFuncSetDate                 DontEnum|Function       1
+  setUTCDate            dateProtoFuncSetUTCDate              DontEnum|Function       1
+  setMonth              dateProtoFuncSetMonth                DontEnum|Function       2
+  setUTCMonth           dateProtoFuncSetUTCMonth             DontEnum|Function       2
+  setFullYear           dateProtoFuncSetFullYear             DontEnum|Function       3
+  setUTCFullYear        dateProtoFuncSetUTCFullYear          DontEnum|Function       3
+  setYear               dateProtoFuncSetYear                 DontEnum|Function       1
+  getYear               dateProtoFuncGetYear                 DontEnum|Function       0
+@end
+*/
+// ECMA 15.9.4
+
+DatePrototype::DatePrototype(ExecState* exec, PassRefPtr<StructureID> structure)
+    : DateInstance(structure)
+{
+    setInternalValue(jsNaN(exec));
+    // The constructor will be added later, after DateConstructor has been built.
+}
+
+bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    return getStaticFunctionSlot<JSObject>(exec, ExecState::dateTable(exec), this, propertyName, slot);
+}
+
+// Functions
+
+JSValue* dateProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = 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));
+}
+
+JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = 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));
+}
+
+JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = 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));
+}
+
+JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = 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));
+}
+
+JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNontrivialString(exec, "Invalid Date");
+
+#if PLATFORM(MAC)
+    double secs = floor(milli / msPerSecond);
+    return jsNontrivialString(exec, formatLocaleDate(exec, secs, true, true, args));
+#else
+    UNUSED_PARAM(args);
+
+    const bool utc = false;
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return formatLocaleDate(exec, t, LocaleDateAndTime);
+#endif
+}
+
+JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNontrivialString(exec, "Invalid Date");
+
+#if PLATFORM(MAC)
+    double secs = floor(milli / msPerSecond);
+    return jsNontrivialString(exec, formatLocaleDate(exec, secs, true, false, args));
+#else
+    UNUSED_PARAM(args);
+
+    const bool utc = false;
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return formatLocaleDate(exec, t, LocaleDate);
+#endif
+}
+
+JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNontrivialString(exec, "Invalid Date");
+
+#if PLATFORM(MAC)
+    double secs = floor(milli / msPerSecond);
+    return jsNontrivialString(exec, formatLocaleDate(exec, secs, false, true, args));
+#else
+    UNUSED_PARAM(args);
+
+    const bool utc = false;
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return formatLocaleDate(exec, t, LocaleTime);
+#endif
+}
+
+JSValue* dateProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    return jsNumber(exec, milli);
+}
+
+JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    return jsNumber(exec, milli);
+}
+
+JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, 1900 + t.year);
+}
+
+JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, 1900 + t.year);
+}
+
+JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = 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));
+}
+
+JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.month);
+}
+
+JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.month);
+}
+
+JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.monthDay);
+}
+
+JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.monthDay);
+}
+
+JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.weekDay);
+}
+
+JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.weekDay);
+}
+
+JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.hour);
+}
+
+JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.hour);
+}
+
+JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.minute);
+}
+
+JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.minute);
+}
+
+JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.second);
+}
+
+JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = true;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, t.second);
+}
+
+JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    double secs = floor(milli / msPerSecond);
+    double ms = milli - secs * msPerSecond;
+    return jsNumber(exec, ms);
+}
+
+JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    double secs = floor(milli / msPerSecond);
+    double ms = milli - secs * msPerSecond;
+    return jsNumber(exec, ms);
+}
+
+JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
+}
+
+JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+
+    double milli = timeClip(args.at(exec, 0)->toNumber(exec));
+    JSValue* result = jsNumber(exec, milli);
+    thisDateObj->setInternalValue(result);
+    return result;
+}
+
+static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSValue* thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue);
+    double milli = thisDateObj->internalNumber();
+    
+    if (args.isEmpty() || isnan(milli)) {
+        JSValue* result = jsNaN(exec);
+        thisDateObj->setInternalValue(result);
+        return result;
+    }
+     
+    double secs = floor(milli / msPerSecond);
+    double ms = milli - secs * msPerSecond;
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
+
+    if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
+        JSValue* result = jsNaN(exec);
+        thisDateObj->setInternalValue(result);
+        return result;
+    } 
+    
+    JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+    thisDateObj->setInternalValue(result);
+    return result;
+}
+
+static JSValue* setNewValueFromDateArgs(ExecState* exec, JSValue* thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    DateInstance* thisDateObj = asDateInstance(thisValue);
+    if (args.isEmpty()) {
+        JSValue* result = jsNaN(exec);
+        thisDateObj->setInternalValue(result);
+        return result;
+    }      
+    
+    double milli = thisDateObj->internalNumber();
+    double ms = 0;
+
+    GregorianDateTime t;
+    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);
+    else {
+        double secs = floor(milli / msPerSecond);
+        ms = milli - secs * msPerSecond;
+        thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
+    }
+    
+    if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
+        JSValue* result = jsNaN(exec);
+        thisDateObj->setInternalValue(result);
+        return result;
+    } 
+           
+    JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+    thisDateObj->setInternalValue(result);
+    return result;
+}
+
+JSValue* dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = false;
+    return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    const bool inputIsUTC = true;
+    return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue);     
+    if (args.isEmpty()) { 
+        JSValue* result = jsNaN(exec);
+        thisDateObj->setInternalValue(result);
+        return result;
+    }
+    
+    double milli = thisDateObj->internalNumber();
+    double ms = 0;
+
+    GregorianDateTime 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);
+    else {   
+        double secs = floor(milli / msPerSecond);
+        ms = milli - secs * msPerSecond;
+        thisDateObj->msToGregorianDateTime(milli, utc, t);
+    }
+    
+    bool ok = true;
+    int32_t year = args.at(exec, 0)->toInt32(exec, ok);
+    if (!ok) {
+        JSValue* result = jsNaN(exec);
+        thisDateObj->setInternalValue(result);
+        return result;
+    }
+            
+    t.year = (year > 99 || year < 0) ? year - 1900 : year;
+    JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
+    thisDateObj->setInternalValue(result);
+    return result;
+}
+
+JSValue* dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+
+    const bool utc = false;
+
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (isnan(milli))
+        return jsNaN(exec);
+
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+
+    // NOTE: IE returns the full year even in getYear.
+    return jsNumber(exec, t.year);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/DatePrototype.h b/JavaScriptCore/runtime/DatePrototype.h
new file mode 100644
index 0000000..500b40d
--- /dev/null
+++ b/JavaScriptCore/runtime/DatePrototype.h
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef DatePrototype_h
+#define DatePrototype_h
+
+#include "DateInstance.h"
+
+namespace JSC {
+
+    class ObjectPrototype;
+
+    class DatePrototype : public DateInstance {
+    public:
+        DatePrototype(ExecState*, PassRefPtr<StructureID>);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+    };
+
+} // namespace JSC
+
+#endif // DatePrototype_h
diff --git a/JavaScriptCore/runtime/Error.cpp b/JavaScriptCore/runtime/Error.cpp
new file mode 100644
index 0000000..5e21c8e
--- /dev/null
+++ b/JavaScriptCore/runtime/Error.cpp
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "Error.h"
+
+#include "ConstructData.h"
+#include "ErrorConstructor.h"
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+#include "JSString.h"
+#include "NativeErrorConstructor.h"
+
+namespace JSC {
+
+const char* expressionBeginOffsetPropertyName = "expressionBeginOffset";
+const char* expressionCaretOffsetPropertyName = "expressionCaretOffset";
+const char* expressionEndOffsetPropertyName = "expressionEndOffset";
+
+JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message, int lineNumber, intptr_t sourceID, const UString& sourceURL)
+{
+    JSObject* constructor;
+    const char* name;
+    switch (type) {
+        case EvalError:
+            constructor = exec->lexicalGlobalObject()->evalErrorConstructor();
+            name = "Evaluation error";
+            break;
+        case RangeError:
+            constructor = exec->lexicalGlobalObject()->rangeErrorConstructor();
+            name = "Range error";
+            break;
+        case ReferenceError:
+            constructor = exec->lexicalGlobalObject()->referenceErrorConstructor();
+            name = "Reference error";
+            break;
+        case SyntaxError:
+            constructor = exec->lexicalGlobalObject()->syntaxErrorConstructor();
+            name = "Syntax error";
+            break;
+        case TypeError:
+            constructor = exec->lexicalGlobalObject()->typeErrorConstructor();
+            name = "Type error";
+            break;
+        case URIError:
+            constructor = exec->lexicalGlobalObject()->URIErrorConstructor();
+            name = "URI error";
+            break;
+        default:
+            constructor = exec->lexicalGlobalObject()->errorConstructor();
+            name = "Error";
+            break;
+    }
+
+    ArgList args;
+    if (message.isEmpty())
+        args.append(jsString(exec, name));
+    else
+        args.append(jsString(exec, message));
+    ConstructData constructData;
+    ConstructType constructType = constructor->getConstructData(constructData);
+    JSObject* error = construct(exec, constructor, constructType, constructData, args);
+
+    if (lineNumber != -1)
+        error->putWithAttributes(exec, Identifier(exec, "line"), jsNumber(exec, lineNumber), ReadOnly | DontDelete);
+    if (sourceID != -1)
+        error->putWithAttributes(exec, Identifier(exec, "sourceId"), jsNumber(exec, sourceID), ReadOnly | DontDelete);
+    if (!sourceURL.isNull())
+        error->putWithAttributes(exec, Identifier(exec, "sourceURL"), jsString(exec, sourceURL), ReadOnly | DontDelete);
+
+    return error;
+}
+
+JSObject* Error::create(ExecState* exec, ErrorType type, const char* message)
+{
+    return create(exec, type, message, -1, -1, NULL);
+}
+
+JSObject* throwError(ExecState* exec, ErrorType type)
+{
+    JSObject* error = Error::create(exec, type, UString(), -1, -1, NULL);
+    exec->setException(error);
+    return error;
+}
+
+JSObject* throwError(ExecState* exec, ErrorType type, const UString& message)
+{
+    JSObject* error = Error::create(exec, type, message, -1, -1, NULL);
+    exec->setException(error);
+    return error;
+}
+
+JSObject* throwError(ExecState* exec, ErrorType type, const char* message)
+{
+    JSObject* error = Error::create(exec, type, message, -1, -1, NULL);
+    exec->setException(error);
+    return error;
+}
+
+JSObject* throwError(ExecState* exec, ErrorType type, const UString& message, int line, intptr_t sourceID, const UString& sourceURL)
+{
+    JSObject* error = Error::create(exec, type, message, line, sourceID, sourceURL);
+    exec->setException(error);
+    return error;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/Error.h b/JavaScriptCore/runtime/Error.h
new file mode 100644
index 0000000..adf7fdf
--- /dev/null
+++ b/JavaScriptCore/runtime/Error.h
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef Error_h
+#define Error_h
+
+#include <stdint.h>
+
+namespace JSC {
+
+    class ExecState;
+    class JSObject;
+    class UString;
+
+    /**
+     * Types of Native Errors available. For custom errors, GeneralError
+     * should be used.
+     */
+    enum ErrorType {
+        GeneralError   = 0,
+        EvalError      = 1,
+        RangeError     = 2,
+        ReferenceError = 3,
+        SyntaxError    = 4,
+        TypeError      = 5,
+        URIError       = 6
+    };
+    
+    extern const char* expressionBeginOffsetPropertyName;
+    extern const char* expressionCaretOffsetPropertyName;
+    extern const char* expressionEndOffsetPropertyName;
+    
+    class Error {
+    public:
+        static JSObject* create(ExecState*, ErrorType, const UString& message, int lineNumber, intptr_t sourceID, const UString& sourceURL);
+        static JSObject* create(ExecState*, ErrorType, const char* message);
+    };
+
+    JSObject* throwError(ExecState*, ErrorType, const UString& message, int lineNumber, intptr_t sourceID, const UString& sourceURL);
+    JSObject* throwError(ExecState*, ErrorType, const UString& message);
+    JSObject* throwError(ExecState*, ErrorType, const char* message);
+    JSObject* throwError(ExecState*, ErrorType);
+
+} // namespace JSC
+
+#endif // Error_h
diff --git a/JavaScriptCore/runtime/ErrorConstructor.cpp b/JavaScriptCore/runtime/ErrorConstructor.cpp
new file mode 100644
index 0000000..3c83fd4
--- /dev/null
+++ b/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "ErrorConstructor.h"
+
+#include "ErrorPrototype.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
+
+ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<StructureID> structure, ErrorPrototype* errorPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, errorPrototype->classInfo()->className))
+{
+    // ECMA 15.11.3.1 Error.prototype
+    putDirectWithoutTransition(exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly);
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), DontDelete | ReadOnly | DontEnum);
+}
+
+// ECMA 15.9.3
+ErrorInstance* constructError(ExecState* exec, const ArgList& args)
+{
+    ErrorInstance* obj = new (exec) ErrorInstance(exec->lexicalGlobalObject()->errorStructure());
+    if (!args.at(exec, 0)->isUndefined())
+        obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0)->toString(exec)));
+    return obj;
+}
+
+static JSObject* constructWithErrorConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructError(exec, args);
+}
+
+ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithErrorConstructor;
+    return ConstructTypeHost;
+}
+
+// ECMA 15.9.2
+static JSValue* callErrorConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    // "Error()" gives the sames result as "new Error()"
+    return constructError(exec, args);
+}
+
+CallType ErrorConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callErrorConstructor;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ErrorConstructor.h b/JavaScriptCore/runtime/ErrorConstructor.h
new file mode 100644
index 0000000..45e4bb0
--- /dev/null
+++ b/JavaScriptCore/runtime/ErrorConstructor.h
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef ErrorConstructor_h
+#define ErrorConstructor_h
+
+#include "ErrorInstance.h"
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class ErrorPrototype;
+
+    class ErrorConstructor : public InternalFunction {
+    public:
+        ErrorConstructor(ExecState*, PassRefPtr<StructureID>, ErrorPrototype*);
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+    ErrorInstance* constructError(ExecState*, const ArgList&);
+
+} // namespace JSC
+
+#endif // ErrorConstructor_h
diff --git a/JavaScriptCore/runtime/ErrorInstance.cpp b/JavaScriptCore/runtime/ErrorInstance.cpp
new file mode 100644
index 0000000..1c55856
--- /dev/null
+++ b/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "ErrorInstance.h"
+
+namespace JSC {
+
+const ClassInfo ErrorInstance::info = { "Error", 0, 0, 0 };
+
+ErrorInstance::ErrorInstance(PassRefPtr<StructureID> structure)
+    : JSObject(structure)
+{
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ErrorInstance.h b/JavaScriptCore/runtime/ErrorInstance.h
new file mode 100644
index 0000000..8d86eec
--- /dev/null
+++ b/JavaScriptCore/runtime/ErrorInstance.h
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef ErrorInstance_h
+#define ErrorInstance_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class ErrorInstance : public JSObject {
+    public:
+        explicit ErrorInstance(PassRefPtr<StructureID>);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+    };
+
+} // namespace JSC
+
+#endif // ErrorInstance_h
diff --git a/JavaScriptCore/runtime/ErrorPrototype.cpp b/JavaScriptCore/runtime/ErrorPrototype.cpp
new file mode 100644
index 0000000..69255c1
--- /dev/null
+++ b/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "ErrorPrototype.h"
+
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+#include "ustring.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
+
+static JSValue* errorProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+// ECMA 15.9.4
+ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+    : ErrorInstance(structure)
+{
+    // The constructor will be added later in ErrorConstructor's constructor
+
+    putDirectWithoutTransition(exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
+    putDirectWithoutTransition(exec->propertyNames().message, jsNontrivialString(exec, "Unknown error"), DontEnum);
+
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
+}
+
+JSValue* errorProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    UString s = "Error";
+
+    JSValue* v = thisObj->get(exec, exec->propertyNames().name);
+    if (!v->isUndefined())
+        s = v->toString(exec);
+
+    v = thisObj->get(exec, exec->propertyNames().message);
+    if (!v->isUndefined()) {
+        // Mozilla-compatible format.
+        s += ": ";
+        s += v->toString(exec);
+    }
+
+    return jsNontrivialString(exec, s);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ErrorPrototype.h b/JavaScriptCore/runtime/ErrorPrototype.h
new file mode 100644
index 0000000..255ea11
--- /dev/null
+++ b/JavaScriptCore/runtime/ErrorPrototype.h
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef ErrorPrototype_h
+#define ErrorPrototype_h
+
+#include "ErrorInstance.h"
+
+namespace JSC {
+
+    class ObjectPrototype;
+
+    class ErrorPrototype : public ErrorInstance {
+    public:
+        ErrorPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+    };
+
+} // namespace JSC
+
+#endif // ErrorPrototype_h
diff --git a/JavaScriptCore/runtime/ExecState.cpp b/JavaScriptCore/runtime/ExecState.cpp
new file mode 100644
index 0000000..0144c14
--- /dev/null
+++ b/JavaScriptCore/runtime/ExecState.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ExecState.h"
+
+#include "CodeBlock.h"
+
+namespace JSC {
+
+JSValue* CallFrame::thisValue()
+{
+    return this[codeBlock()->thisRegister].jsValue(this);
+}
+
+}
diff --git a/JavaScriptCore/runtime/ExecState.h b/JavaScriptCore/runtime/ExecState.h
new file mode 100644
index 0000000..f1891bb
--- /dev/null
+++ b/JavaScriptCore/runtime/ExecState.h
@@ -0,0 +1,148 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ExecState_h
+#define ExecState_h
+
+// FIXME: Rename this file to CallFrame.h.
+
+#include "JSGlobalData.h"
+#include "Machine.h"
+#include "ScopeChain.h"
+
+namespace JSC  {
+
+    class Arguments;
+    class JSActivation;
+
+    // Represents the current state of script execution.
+    // Passed as the first argument to most functions.
+    class ExecState : private Register {
+    public:
+        JSFunction* callee() const { return this[RegisterFile::Callee].function(); }
+        CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
+        ScopeChainNode* scopeChain() const { return this[RegisterFile::ScopeChain].Register::scopeChain(); }
+
+        JSValue* thisValue();
+
+        // Global object in which execution began.
+        JSGlobalObject* dynamicGlobalObject();
+
+        // Global object in which the currently executing code was defined.
+        // Differs from dynamicGlobalObject() during function calls across web browser frames.
+        JSGlobalObject* lexicalGlobalObject() const
+        {
+            return scopeChain()->globalObject();
+        }
+
+        // Differs from lexicalGlobalObject because this will have DOM window shell rather than
+        // the actual DOM window, which can't be "this" for security reasons.
+        JSObject* globalThisValue() const
+        {
+            return scopeChain()->globalThisObject();
+        }
+
+        // FIXME: Elsewhere, we use JSGlobalData* rather than JSGlobalData&.
+        // We should make this more uniform and either use a reference everywhere
+        // or a pointer everywhere.
+        JSGlobalData& globalData() const
+        {
+            return *scopeChain()->globalData;
+        }
+
+        // Convenience functions for access to global data.
+        // It takes a few memory references to get from a call frame to the global data
+        // pointer, so these are inefficient, and should be used sparingly in new code.
+        // But they're used in many places in legacy code, so they're not going away any time soon.
+
+        void setException(JSValue* exception) { globalData().exception = exception; }
+        void clearException() { globalData().exception = noValue(); }
+        JSValue* exception() const { return globalData().exception; }
+        JSValue** exceptionSlot() { return &globalData().exception; }
+        bool hadException() const { return !!globalData().exception; }
+
+        const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
+        const ArgList& emptyList() const { return *globalData().emptyList; }
+        Machine* machine() { return globalData().machine; }
+        Heap* heap() { return &globalData().heap; }
+
+        static const HashTable* arrayTable(CallFrame* callFrame) { return callFrame->globalData().arrayTable; }
+        static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; }
+        static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
+        static const HashTable* numberTable(CallFrame* callFrame) { return callFrame->globalData().numberTable; }
+        static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
+        static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
+        static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
+
+    private:
+        friend class Arguments;
+        friend class JSActivation;
+        friend class JSGlobalObject;
+        friend class Machine;
+
+        static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
+        Register* registers() { return this; }
+
+        CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
+
+        int argumentCount() const { return this[RegisterFile::ArgumentCount].i(); }
+        CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
+        Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); }
+        Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); }
+        int returnValueRegister() const { return this[RegisterFile::ReturnValueRegister].i(); }
+
+        void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = count; }
+        void setCallee(JSFunction* callee) { this[RegisterFile::Callee] = callee; }
+        void setCalleeArguments(Arguments* arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; }
+        void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; }
+        void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; }
+        void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; }
+
+        ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain,
+            CallFrame* callerFrame, int returnValueRegister, int argc, JSFunction* function)
+        {
+            ASSERT(callerFrame); // Use noCaller() rather than 0 for the outer host call frame caller.
+
+            setCodeBlock(codeBlock);
+            setScopeChain(scopeChain);
+            setCallerFrame(callerFrame);
+            this[RegisterFile::ReturnPC] = vPC;
+            this[RegisterFile::ReturnValueRegister] = returnValueRegister;
+            setArgumentCount(argc); // original argument count (for the sake of the "arguments" object)
+            setCallee(function);
+            setCalleeArguments(0);
+        }
+
+        static const intptr_t HostCallFrameFlag = 1;
+
+        static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); }
+        bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; }
+        CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); }
+        CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); }
+
+        ExecState();
+        ~ExecState();
+    };
+
+} // namespace JSC
+
+#endif // ExecState_h
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
new file mode 100644
index 0000000..adc3d3c
--- /dev/null
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -0,0 +1,146 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "FunctionConstructor.h"
+
+#include "FunctionPrototype.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+#include "Parser.h"
+#include "Debugger.h"
+#include "lexer.h"
+#include "nodes.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
+
+FunctionConstructor::FunctionConstructor(ExecState* exec, PassRefPtr<StructureID> structure, FunctionPrototype* functionPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, functionPrototype->classInfo()->className))
+{
+    putDirectWithoutTransition(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
+
+    // Number of arguments for constructor
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
+}
+
+static JSObject* constructWithFunctionConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructFunction(exec, args);
+}
+
+ConstructType FunctionConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithFunctionConstructor;
+    return ConstructTypeHost;
+}
+
+static JSValue* callFunctionConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructFunction(exec, args);
+}
+
+// ECMA 15.3.1 The Function Constructor Called as a Function
+CallType FunctionConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callFunctionConstructor;
+    return CallTypeHost;
+}
+
+// ECMA 15.3.2 The Function Constructor
+JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
+{
+    UString p("");
+    UString body;
+    int argsSize = args.size();
+    if (argsSize == 0)
+        body = "";
+    else if (argsSize == 1)
+        body = args.at(exec, 0)->toString(exec);
+    else {
+        p = args.at(exec, 0)->toString(exec);
+        for (int k = 1; k < argsSize - 1; k++)
+            p += "," + args.at(exec, k)->toString(exec);
+        body = args.at(exec, argsSize - 1)->toString(exec);
+    }
+
+    // parse the source code
+    int errLine;
+    UString errMsg;
+    SourceCode source = makeSource(body, sourceURL, lineNumber);
+    RefPtr<FunctionBodyNode> functionBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
+
+    // No program node == syntax error - throw a syntax error
+    if (!functionBody)
+        // We can't return a Completion(Throw) here, so just set the exception
+        // and return it
+        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
+
+    // parse parameter list. throw syntax error on illegal identifiers
+    int len = p.size();
+    const UChar* c = p.data();
+    int i = 0;
+    UString param;
+    Vector<Identifier> parameters;
+    while (i < len) {
+        while (*c == ' ' && i < len)
+            c++, i++;
+        if (Lexer::isIdentStart(c[0])) {  // else error
+            param = UString(c, 1);
+            c++, i++;
+            while (i < len && (Lexer::isIdentPart(c[0]))) {
+                param.append(*c);
+                c++, i++;
+            }
+            while (i < len && *c == ' ')
+                c++, i++;
+            if (i == len) {
+                parameters.append(Identifier(exec, param));
+                break;
+            } else if (*c == ',') {
+                parameters.append(Identifier(exec, param));
+                c++, i++;
+                continue;
+            } // else error
+        }
+        return throwError(exec, SyntaxError, "Syntax error in parameter list");
+    }
+    size_t count = parameters.size();
+    functionBody->finishParsing(parameters.releaseBuffer(), count);
+
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
+    JSFunction* function = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
+
+    JSObject* prototype = constructEmptyObject(exec);
+    prototype->putDirect(exec->propertyNames().constructor, function, DontEnum);
+    function->putDirect(exec->propertyNames().prototype, prototype, DontDelete);
+    return function;
+}
+
+// ECMA 15.3.2 The Function Constructor
+JSObject* constructFunction(ExecState* exec, const ArgList& args)
+{
+    return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/FunctionConstructor.h b/JavaScriptCore/runtime/FunctionConstructor.h
new file mode 100644
index 0000000..c309c41
--- /dev/null
+++ b/JavaScriptCore/runtime/FunctionConstructor.h
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  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 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
+ *
+ */
+
+#ifndef FunctionConstructor_h
+#define FunctionConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class FunctionPrototype;
+
+    class FunctionConstructor : public InternalFunction {
+    public:
+        FunctionConstructor(ExecState*, PassRefPtr<StructureID>, FunctionPrototype*);
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+    JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
+    JSObject* constructFunction(ExecState*, const ArgList&);
+
+} // namespace JSC
+
+#endif // FunctionConstructor_h
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
new file mode 100644
index 0000000..8c3a260
--- /dev/null
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -0,0 +1,136 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "FunctionPrototype.h"
+
+#include "Arguments.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "JSString.h"
+#include "Machine.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
+
+static JSValue* functionProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionProtoFuncApply(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* functionProtoFuncCall(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<StructureID> structure)
+    : InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
+{
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
+}
+
+void FunctionPrototype::addFunctionProperties(ExecState* exec, StructureID* prototypeFunctionStructure)
+{
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
+}
+
+static JSValue* callFunctionPrototype(ExecState*, JSObject*, JSValue*, const ArgList&)
+{
+    return jsUndefined();
+}
+
+// ECMA 15.3.4
+CallType FunctionPrototype::getCallData(CallData& callData)
+{
+    callData.native.function = callFunctionPrototype;
+    return CallTypeHost;
+}
+
+// Functions
+
+JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (thisValue->isObject(&JSFunction::info)) {
+        JSFunction* function = asFunction(thisValue);
+        return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->m_body->paramString() + ") " + function->m_body->toSourceString());
+    }
+
+    if (thisValue->isObject(&InternalFunction::info)) {
+        InternalFunction* function = asInternalFunction(thisValue);
+        return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n    [native code]\n}");
+    }
+
+    return throwError(exec, TypeError);
+}
+
+JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    CallData callData;
+    CallType callType = thisValue->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSValue* thisArg = args.at(exec, 0);
+    JSValue* argArray = args.at(exec, 1);
+
+    JSValue* applyThis;
+    if (thisArg->isUndefinedOrNull())
+        applyThis = exec->globalThisValue();
+    else
+        applyThis = thisArg->toObject(exec);
+
+    ArgList applyArgs;
+    if (!argArray->isUndefinedOrNull()) {
+        if (!argArray->isObject())
+            return throwError(exec, TypeError);
+        if (asObject(argArray)->classInfo() == &Arguments::info)
+            asArguments(argArray)->fillArgList(exec, applyArgs);
+        else if (exec->machine()->isJSArray(argArray))
+            asArray(argArray)->fillArgList(exec, applyArgs);
+        else if (asObject(argArray)->inherits(&JSArray::info)) {
+            unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length)->toUInt32(exec);
+            for (unsigned i = 0; i < length; ++i)
+                applyArgs.append(asArray(argArray)->get(exec, i));
+        } else
+            return throwError(exec, TypeError);
+    }
+
+    return call(exec, thisValue, callType, callData, applyThis, applyArgs);
+}
+
+JSValue* functionProtoFuncCall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    CallData callData;
+    CallType callType = thisValue->getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    JSValue* thisArg = args.at(exec, 0);
+
+    JSObject* callThis;
+    if (thisArg->isUndefinedOrNull())
+        callThis = exec->globalThisValue();
+    else
+        callThis = thisArg->toObject(exec);
+
+    ArgList argsTail;
+    args.getSlice(1, argsTail);
+    return call(exec, thisValue, callType, callData, callThis, argsTail);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/FunctionPrototype.h b/JavaScriptCore/runtime/FunctionPrototype.h
new file mode 100644
index 0000000..f493642
--- /dev/null
+++ b/JavaScriptCore/runtime/FunctionPrototype.h
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  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 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
+ *
+ */
+
+#ifndef FunctionPrototype_h
+#define FunctionPrototype_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class FunctionPrototype : public InternalFunction {
+    public:
+        FunctionPrototype(ExecState*, PassRefPtr<StructureID>);
+        void addFunctionProperties(ExecState*, StructureID* prototypeFunctionStructure);
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+        {
+            return StructureID::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+        }
+
+    private:
+        virtual CallType getCallData(CallData&);
+    };
+
+} // namespace JSC
+
+#endif // FunctionPrototype_h
diff --git a/JavaScriptCore/runtime/GetterSetter.cpp b/JavaScriptCore/runtime/GetterSetter.cpp
new file mode 100644
index 0000000..c3d089f
--- /dev/null
+++ b/JavaScriptCore/runtime/GetterSetter.cpp
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "GetterSetter.h"
+
+#include "JSObject.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+void GetterSetter::mark()
+{
+    JSCell::mark();
+
+    if (m_getter && !m_getter->marked())
+        m_getter->mark();
+    if (m_setter && !m_setter->marked())
+        m_setter->mark();
+}
+
+JSValue* GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+    ASSERT_NOT_REACHED();
+    return jsNull();
+}
+
+bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
+{
+    ASSERT_NOT_REACHED();
+    number = 0;
+    value = noValue();
+    return true;
+}
+
+bool GetterSetter::toBoolean(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+double GetterSetter::toNumber(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return 0.0;
+}
+
+UString GetterSetter::toString(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return UString::null();
+}
+
+JSObject* GetterSetter::toObject(ExecState* exec) const
+{
+    ASSERT_NOT_REACHED();
+    return jsNull()->toObject(exec);
+}
+
+bool GetterSetter::isGetterSetter() const
+{
+    return true;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/GetterSetter.h b/JavaScriptCore/runtime/GetterSetter.h
new file mode 100644
index 0000000..da968b2
--- /dev/null
+++ b/JavaScriptCore/runtime/GetterSetter.h
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GetterSetter_h
+#define GetterSetter_h
+
+#include "JSCell.h"
+
+namespace JSC {
+
+    class JSObject;
+
+    // This is an internal value object which stores getter and setter functions
+    // for a property.
+    class GetterSetter : public JSCell {
+    public:
+        GetterSetter()
+            : JSCell(0)
+            , m_getter(0)
+            , m_setter(0)
+        {
+        }
+
+        virtual void mark();
+
+        JSObject* getter() const { return m_getter; }
+        void setGetter(JSObject* getter) { m_getter = getter; }
+        JSObject* setter() const { return m_setter; }
+        void setSetter(JSObject* setter) { m_setter = setter; }
+
+    private:
+        virtual bool isGetterSetter() const;
+
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+
+        JSObject* m_getter;
+        JSObject* m_setter;  
+    };
+
+    GetterSetter* asGetterSetter(JSValue*);
+
+    inline GetterSetter* asGetterSetter(JSValue* value)
+    {
+        ASSERT(asCell(value)->isGetterSetter());
+        return static_cast<GetterSetter*>(asCell(value));
+    }
+
+
+} // namespace JSC
+
+#endif // GetterSetter_h
diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/JavaScriptCore/runtime/GlobalEvalFunction.cpp
new file mode 100644
index 0000000..10b3a2f
--- /dev/null
+++ b/JavaScriptCore/runtime/GlobalEvalFunction.cpp
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "GlobalEvalFunction.h"
+
+#include "JSGlobalObject.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction);
+
+GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, PassRefPtr<StructureID> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
+    : PrototypeFunction(exec, structure, len, name, function)
+    , m_cachedGlobalObject(cachedGlobalObject)
+{
+    ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
+}
+
+void GlobalEvalFunction::mark()
+{
+    PrototypeFunction::mark();
+    if (!m_cachedGlobalObject->marked())
+        m_cachedGlobalObject->mark();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.h b/JavaScriptCore/runtime/GlobalEvalFunction.h
new file mode 100644
index 0000000..2d207c4
--- /dev/null
+++ b/JavaScriptCore/runtime/GlobalEvalFunction.h
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GlobalEvalFunction_h
+#define GlobalEvalFunction_h
+
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+    class JSGlobalObject;
+
+    class GlobalEvalFunction : public PrototypeFunction {
+    public:
+        GlobalEvalFunction(ExecState*, PassRefPtr<StructureID>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
+        JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
+
+    private:
+        virtual void mark();
+
+        JSGlobalObject* m_cachedGlobalObject;
+    };
+
+} // namespace JSC
+
+#endif // GlobalEvalFunction_h
diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp
new file mode 100644
index 0000000..9e14768
--- /dev/null
+++ b/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InitializeThreading.h"
+
+#include "collector.h"
+#include "DateMath.h"
+#include "dtoa.h"
+#include "identifier.h"
+#include "JSGlobalObject.h"
+#include "ustring.h"
+#include <wtf/Threading.h>
+
+namespace JSC {
+
+#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
+static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
+#endif
+
+static void initializeThreadingOnce()
+{
+    WTF::initializeThreading();
+#if ENABLE(JSC_MULTIPLE_THREADS)
+    s_dtoaP5Mutex = new Mutex;
+    UString::null();
+    initDateMath();
+#endif
+}
+
+void initializeThreading()
+{
+#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
+    pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce);
+#else
+    static bool initializedThreading = false;
+    if (!initializedThreading) {
+        initializeThreadingOnce();
+        initializedThreading = true;
+    }
+#endif
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/InitializeThreading.h b/JavaScriptCore/runtime/InitializeThreading.h
new file mode 100644
index 0000000..1a93ccb
--- /dev/null
+++ b/JavaScriptCore/runtime/InitializeThreading.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 InitializeThreading_h
+#define InitializeThreading_h
+
+namespace JSC {
+
+    // This function must be called from the main thread. It is safe to call it repeatedly.
+    // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
+    void initializeThreading();
+
+}
+
+#endif // InitializeThreading_h
diff --git a/JavaScriptCore/runtime/InternalFunction.cpp b/JavaScriptCore/runtime/InternalFunction.cpp
new file mode 100644
index 0000000..ee81a58
--- /dev/null
+++ b/JavaScriptCore/runtime/InternalFunction.cpp
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "InternalFunction.h"
+
+#include "FunctionPrototype.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(InternalFunction);
+
+const ClassInfo InternalFunction::info = { "Function", 0, 0, 0 };
+
+const ClassInfo* InternalFunction::classInfo() const
+{
+    return &info;
+}
+
+InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<StructureID> structure, const Identifier& name)
+    : JSObject(structure)
+{
+    putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum);
+}
+
+const UString& InternalFunction::name(JSGlobalData* globalData)
+{
+    return asString(getDirect(globalData->propertyNames->name))->value();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/InternalFunction.h b/JavaScriptCore/runtime/InternalFunction.h
new file mode 100644
index 0000000..54d90ae
--- /dev/null
+++ b/JavaScriptCore/runtime/InternalFunction.h
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef InternalFunction_h
+#define InternalFunction_h
+
+#include "JSObject.h"
+#include "identifier.h"
+
+namespace JSC {
+
+    class FunctionPrototype;
+
+    class InternalFunction : public JSObject {
+    public:
+        virtual const ClassInfo* classInfo() const; 
+        static const ClassInfo info;
+
+        const UString& name(JSGlobalData*);
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto) 
+        { 
+            return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); 
+        }
+
+    protected:
+        InternalFunction(PassRefPtr<StructureID> structure) : JSObject(structure) { }
+        InternalFunction(JSGlobalData*, PassRefPtr<StructureID>, const Identifier&);
+
+    private:
+        virtual CallType getCallData(CallData&) = 0;
+    };
+
+    InternalFunction* asInternalFunction(JSValue*);
+
+    inline InternalFunction* asInternalFunction(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&InternalFunction::info));
+        return static_cast<InternalFunction*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // InternalFunction_h
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
new file mode 100644
index 0000000..9cb77e8
--- /dev/null
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#include "config.h"
+#include "JSActivation.h"
+
+#include "Arguments.h"
+#include "Machine.h"
+#include "JSFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSActivation);
+
+const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
+
+JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionBodyNode> functionBody)
+    : Base(callFrame->globalData().activationStructureID, new JSActivationData(functionBody, callFrame))
+{
+}
+
+JSActivation::~JSActivation()
+{
+    delete d();
+}
+
+void JSActivation::mark()
+{
+    Base::mark();
+
+    Register* registerArray = d()->registerArray.get();
+    if (!registerArray)
+        return;
+
+    size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
+
+    size_t i = 0;
+    size_t count = numParametersMinusThis; 
+    for ( ; i < count; ++i) {
+        Register& r = registerArray[i];
+        if (!r.marked())
+            r.mark();
+    }
+
+    size_t numVars = d()->functionBody->generatedByteCode().numVars;
+
+    // Skip the call frame, which sits between the parameters and vars.
+    i += RegisterFile::CallFrameHeaderSize;
+    count += RegisterFile::CallFrameHeaderSize + numVars;
+
+    for ( ; i < count; ++i) {
+        Register& r = registerArray[i];
+        if (!r.marked())
+            r.mark();
+    }
+}
+
+bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (symbolTableGet(propertyName, slot))
+        return true;
+
+    if (JSValue** location = getDirectLocation(propertyName)) {
+        slot.setValueSlot(location);
+        return true;
+    }
+
+    // Only return the built-in arguments object if it wasn't overridden above.
+    if (propertyName == exec->propertyNames().arguments) {
+        slot.setCustom(this, getArgumentsGetter());
+        return true;
+    }
+
+    // We don't call through to JSObject because there's no way to give an 
+    // activation object getter properties or a prototype.
+    ASSERT(!hasGetterSetterProperties());
+    ASSERT(prototype()->isNull());
+    return false;
+}
+
+void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    if (symbolTablePut(propertyName, value))
+        return;
+
+    // We don't call through to JSObject because __proto__ and getter/setter 
+    // properties are non-standard extensions that other implementations do not
+    // expose in the activation object.
+    ASSERT(!hasGetterSetterProperties());
+    putDirect(propertyName, value, 0, true, slot);
+}
+
+// FIXME: Make this function honor ReadOnly (const) and DontEnum
+void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    if (symbolTablePutWithAttributes(propertyName, value, attributes))
+        return;
+
+    // We don't call through to JSObject because __proto__ and getter/setter 
+    // properties are non-standard extensions that other implementations do not
+    // expose in the activation object.
+    ASSERT(!hasGetterSetterProperties());
+    PutPropertySlot slot;
+    putDirect(propertyName, value, attributes, true, slot);
+}
+
+bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    if (propertyName == exec->propertyNames().arguments)
+        return false;
+
+    return Base::deleteProperty(exec, propertyName);
+}
+
+JSObject* JSActivation::toThisObject(ExecState* exec) const
+{
+    return exec->globalThisValue();
+}
+
+bool JSActivation::isDynamicScope() const
+{
+    return d()->functionBody->usesEval();
+}
+
+JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    JSActivation* activation = asActivation(slot.slotBase());
+
+    if (activation->d()->functionBody->usesArguments()) {
+        PropertySlot slot;
+        activation->symbolTableGet(exec->propertyNames().arguments, slot);
+        return slot.getValue(exec, exec->propertyNames().arguments);
+    }
+
+    CallFrame* callFrame = CallFrame::create(activation->d()->registers);
+    Arguments* arguments = callFrame->optionalCalleeArguments();
+    if (!arguments) {
+        arguments = new (callFrame) Arguments(callFrame);
+        arguments->copyRegisters();
+        callFrame->setCalleeArguments(arguments);
+    }
+    ASSERT(arguments->isObject(&Arguments::info));
+
+    return arguments;
+}
+
+// These two functions serve the purpose of isolating the common case from a
+// PIC branch.
+
+PropertySlot::GetValueFunc JSActivation::getArgumentsGetter()
+{
+    return argumentsGetter;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
new file mode 100644
index 0000000..16d131b
--- /dev/null
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 JSActivation_h
+#define JSActivation_h
+
+#include "CodeBlock.h"
+#include "JSVariableObject.h"
+#include "RegisterFile.h"
+#include "SymbolTable.h"
+#include "nodes.h"
+
+namespace JSC {
+
+    class Arguments;
+    class Register;
+    
+    class JSActivation : public JSVariableObject {
+        typedef JSVariableObject Base;
+    public:
+        JSActivation(CallFrame*, PassRefPtr<FunctionBodyNode>);
+        virtual ~JSActivation();
+
+        virtual void mark();
+
+        virtual bool isDynamicScope() const;
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
+
+        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+
+        virtual JSObject* toThisObject(ExecState*) const;
+
+        void copyRegisters(Arguments* arguments);
+        
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+
+    private:
+        struct JSActivationData : public JSVariableObjectData {
+            JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
+                : JSVariableObjectData(&functionBody->symbolTable(), registers)
+                , functionBody(functionBody)
+            {
+            }
+
+            RefPtr<FunctionBodyNode> functionBody;
+        };
+        
+        static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+        NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
+
+        JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
+    };
+
+    JSActivation* asActivation(JSValue*);
+
+    inline JSActivation* asActivation(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&JSActivation::info));
+        return static_cast<JSActivation*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // JSActivation_h
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
new file mode 100644
index 0000000..d2d38a4
--- /dev/null
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -0,0 +1,1002 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ *  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 "JSArray.h"
+
+#include "ArrayPrototype.h"
+#include "PropertyNameArray.h"
+#include <wtf/AVLTree.h>
+#include <wtf/Assertions.h>
+#include <operations.h>
+
+#define CHECK_ARRAY_CONSISTENCY 0
+
+using namespace std;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSArray);
+
+// Overview of JSArray
+//
+// Properties of JSArray objects may be stored in one of three locations:
+//   * The regular JSObject property map.
+//   * A storage vector.
+//   * A sparse map of array entries.
+//
+// Properties with non-numeric identifiers, with identifiers that are not representable
+// as an unsigned integer, or where the value is greater than  MAX_ARRAY_INDEX
+// (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit
+// integer) are not considered array indices and will be stored in the JSObject property map.
+//
+// All properties with a numeric identifer, representable as an unsigned integer i,
+// where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the
+// storage vector or the sparse map.  An array index i will be handled in the following
+// fashion:
+//
+//   * Where (i < MIN_SPARSE_ARRAY_INDEX) the value will be stored in the storage vector.
+//   * Where (MIN_SPARSE_ARRAY_INDEX <= i <= MAX_STORAGE_VECTOR_INDEX) the value will either
+//     be stored in the storage vector or in the sparse array, depending on the density of
+//     data that would be stored in the vector (a vector being used where at least
+//     (1 / minDensityMultiplier) of the entries would be populated).
+//   * Where (MAX_STORAGE_VECTOR_INDEX < i <= MAX_ARRAY_INDEX) the value will always be stored
+//     in the sparse array.
+
+// The definition of MAX_STORAGE_VECTOR_LENGTH is dependant on the definition storageSize
+// function below - the MAX_STORAGE_VECTOR_LENGTH limit is defined such that the storage
+// size calculation cannot overflow.  (sizeof(ArrayStorage) - sizeof(JSValue*)) +
+// (vectorLength * sizeof(JSValue*)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
+#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValue*))) / sizeof(JSValue*))
+
+// These values have to be macros to be used in max() and min() without introducing
+// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
+#define MIN_SPARSE_ARRAY_INDEX 10000U
+#define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1)
+// 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer.
+#define MAX_ARRAY_INDEX 0xFFFFFFFEU
+
+// Our policy for when to use a vector and when to use a sparse map.
+// For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector.
+// When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector
+// as long as it is 1/8 full. If more sparse than that, we use a map.
+static const unsigned minDensityMultiplier = 8;
+
+const ClassInfo JSArray::info = {"Array", 0, 0, 0};
+
+static inline size_t storageSize(unsigned vectorLength)
+{
+    ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH);
+
+    // MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH)
+    // - as asserted above - the following calculation cannot overflow.
+    size_t size = (sizeof(ArrayStorage) - sizeof(JSValue*)) + (vectorLength * sizeof(JSValue*));
+    // Assertion to detect integer overflow in previous calculation (should not be possible, provided that
+    // MAX_STORAGE_VECTOR_LENGTH is correctly defined).
+    ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValue*))) / sizeof(JSValue*) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValue*))));
+
+    return size;
+}
+
+static inline unsigned increasedVectorLength(unsigned newLength)
+{
+    ASSERT(newLength <= MAX_STORAGE_VECTOR_LENGTH);
+
+    // Mathematically equivalent to:
+    //   increasedLength = (newLength * 3 + 1) / 2;
+    // or:
+    //   increasedLength = (unsigned)ceil(newLength * 1.5));
+    // This form is not prone to internal overflow.
+    unsigned increasedLength = newLength + (newLength >> 1) + (newLength & 1);
+    ASSERT(increasedLength >= newLength);
+
+    return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH);
+}
+
+static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
+{
+    return length / minDensityMultiplier <= numValues;
+}
+
+#if !CHECK_ARRAY_CONSISTENCY
+
+inline void JSArray::checkConsistency(ConsistencyCheckType)
+{
+}
+
+#endif
+
+JSArray::JSArray(PassRefPtr<StructureID> structureID)
+    : JSObject(structureID)
+{
+    unsigned initialCapacity = 0;
+
+    m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
+    m_fastAccessCutoff = 0;
+    m_storage->m_vectorLength = initialCapacity;
+    m_storage->m_length = 0;
+
+    checkConsistency();
+}
+
+JSArray::JSArray(PassRefPtr<StructureID> structure, unsigned initialLength)
+    : JSObject(structure)
+{
+    unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
+
+    m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
+    m_fastAccessCutoff = 0;
+    m_storage->m_vectorLength = initialCapacity;
+    m_storage->m_length = initialLength;
+
+    Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue*));
+
+    checkConsistency();
+}
+
+JSArray::JSArray(ExecState* exec, PassRefPtr<StructureID> structure, const ArgList& list)
+    : JSObject(structure)
+{
+    unsigned length = list.size();
+
+    m_fastAccessCutoff = length;
+
+    ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(length)));
+
+    storage->m_vectorLength = length;
+    storage->m_numValuesInVector = length;
+    storage->m_sparseValueMap = 0;
+    storage->m_length = length;
+
+    size_t i = 0;
+    ArgList::const_iterator end = list.end();
+    for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
+        storage->m_vector[i] = (*it).jsValue(exec);
+
+    m_storage = storage;
+
+    // When the array is created non-empty, its cells are filled, so it's really no worse than
+    // a property map. Therefore don't report extra memory cost.
+
+    checkConsistency();
+}
+
+JSArray::~JSArray()
+{
+    checkConsistency(DestructorConsistencyCheck);
+
+    delete m_storage->m_sparseValueMap;
+    fastFree(m_storage);
+}
+
+bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
+{
+    ArrayStorage* storage = m_storage;
+
+    if (i >= storage->m_length) {
+        if (i > MAX_ARRAY_INDEX)
+            return getOwnPropertySlot(exec, Identifier::from(exec, i), slot);
+        return false;
+    }
+
+    if (i < storage->m_vectorLength) {
+        JSValue*& valueSlot = storage->m_vector[i];
+        if (valueSlot) {
+            slot.setValueSlot(&valueSlot);
+            return true;
+        }
+    } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+        if (i >= MIN_SPARSE_ARRAY_INDEX) {
+            SparseArrayValueMap::iterator it = map->find(i);
+            if (it != map->end()) {
+                slot.setValueSlot(&it->second);
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (propertyName == exec->propertyNames().length) {
+        slot.setValue(jsNumber(exec, length()));
+        return true;
+    }
+
+    bool isArrayIndex;
+    unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+    if (isArrayIndex)
+        return JSArray::getOwnPropertySlot(exec, i, slot);
+
+    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+// ECMA 15.4.5.1
+void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    bool isArrayIndex;
+    unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+    if (isArrayIndex) {
+        put(exec, i, value);
+        return;
+    }
+
+    if (propertyName == exec->propertyNames().length) {
+        unsigned newLength = value->toUInt32(exec);
+        if (value->toNumber(exec) != static_cast<double>(newLength)) {
+            throwError(exec, RangeError, "Invalid array length.");
+            return;
+        }
+        setLength(newLength);
+        return;
+    }
+
+    JSObject::put(exec, propertyName, value, slot);
+}
+
+void JSArray::put(ExecState* exec, unsigned i, JSValue* value)
+{
+    checkConsistency();
+
+    unsigned length = m_storage->m_length;
+    if (i >= length && i <= MAX_ARRAY_INDEX) {
+        length = i + 1;
+        m_storage->m_length = length;
+    }
+
+    if (i < m_storage->m_vectorLength) {
+        JSValue*& valueSlot = m_storage->m_vector[i];
+        if (valueSlot) {
+            valueSlot = value;
+            checkConsistency();
+            return;
+        }
+        valueSlot = value;
+        if (++m_storage->m_numValuesInVector == m_storage->m_length)
+            m_fastAccessCutoff = m_storage->m_length;
+        checkConsistency();
+        return;
+    }
+
+    putSlowCase(exec, i, value);
+}
+
+NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue* value)
+{
+    ArrayStorage* storage = m_storage;
+    SparseArrayValueMap* map = storage->m_sparseValueMap;
+
+    if (i >= MIN_SPARSE_ARRAY_INDEX) {
+        if (i > MAX_ARRAY_INDEX) {
+            PutPropertySlot slot;
+            put(exec, Identifier::from(exec, i), value, slot);
+            return;
+        }
+
+        // We miss some cases where we could compact the storage, such as a large array that is being filled from the end
+        // (which will only be compacted as we reach indices that are less than cutoff) - but this makes the check much faster.
+        if ((i > MAX_STORAGE_VECTOR_INDEX) || !isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) {
+            if (!map) {
+                map = new SparseArrayValueMap;
+                storage->m_sparseValueMap = map;
+            }
+            map->set(i, value);
+            return;
+        }
+    }
+
+    // We have decided that we'll put the new item into the vector.
+    // Fast case is when there is no sparse map, so we can increase the vector size without moving values from it.
+    if (!map || map->isEmpty()) {
+        if (increaseVectorLength(i + 1)) {
+            storage = m_storage;
+            storage->m_vector[i] = value;
+            if (++storage->m_numValuesInVector == storage->m_length)
+                m_fastAccessCutoff = storage->m_length;
+            checkConsistency();
+        } else
+            throwOutOfMemoryError(exec);
+        return;
+    }
+
+    // Decide how many values it would be best to move from the map.
+    unsigned newNumValuesInVector = storage->m_numValuesInVector + 1;
+    unsigned newVectorLength = increasedVectorLength(i + 1);
+    for (unsigned j = max(storage->m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
+        newNumValuesInVector += map->contains(j);
+    if (i >= MIN_SPARSE_ARRAY_INDEX)
+        newNumValuesInVector -= map->contains(i);
+    if (isDenseEnoughForVector(newVectorLength, newNumValuesInVector)) {
+        unsigned proposedNewNumValuesInVector = newNumValuesInVector;
+        // If newVectorLength is already the maximum - MAX_STORAGE_VECTOR_LENGTH - then do not attempt to grow any further.
+        while (newVectorLength < MAX_STORAGE_VECTOR_LENGTH) {
+            unsigned proposedNewVectorLength = increasedVectorLength(newVectorLength + 1);
+            for (unsigned j = max(newVectorLength, MIN_SPARSE_ARRAY_INDEX); j < proposedNewVectorLength; ++j)
+                proposedNewNumValuesInVector += map->contains(j);
+            if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector))
+                break;
+            newVectorLength = proposedNewVectorLength;
+            newNumValuesInVector = proposedNewNumValuesInVector;
+        }
+    }
+
+    storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));
+    if (!storage) {
+        throwOutOfMemoryError(exec);
+        return;
+    }
+
+    unsigned vectorLength = storage->m_vectorLength;
+    if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
+        for (unsigned j = vectorLength; j < newVectorLength; ++j)
+            storage->m_vector[j] = noValue();
+        if (i > MIN_SPARSE_ARRAY_INDEX)
+            map->remove(i);
+    } else {
+        for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)
+            storage->m_vector[j] = noValue();
+        for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
+            storage->m_vector[j] = map->take(j);
+    }
+
+    storage->m_vector[i] = value;
+
+    storage->m_vectorLength = newVectorLength;
+    storage->m_numValuesInVector = newNumValuesInVector;
+
+    m_storage = storage;
+
+    checkConsistency();
+}
+
+bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    bool isArrayIndex;
+    unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+    if (isArrayIndex)
+        return deleteProperty(exec, i);
+
+    if (propertyName == exec->propertyNames().length)
+        return false;
+
+    return JSObject::deleteProperty(exec, propertyName);
+}
+
+bool JSArray::deleteProperty(ExecState* exec, unsigned i)
+{
+    checkConsistency();
+
+    ArrayStorage* storage = m_storage;
+
+    if (i < storage->m_vectorLength) {
+        JSValue*& valueSlot = storage->m_vector[i];
+        if (!valueSlot) {
+            checkConsistency();
+            return false;
+        }
+        valueSlot = noValue();
+        --storage->m_numValuesInVector;
+        if (m_fastAccessCutoff > i)
+            m_fastAccessCutoff = i;
+        checkConsistency();
+        return true;
+    }
+
+    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+        if (i >= MIN_SPARSE_ARRAY_INDEX) {
+            SparseArrayValueMap::iterator it = map->find(i);
+            if (it != map->end()) {
+                map->remove(it);
+                checkConsistency();
+                return true;
+            }
+        }
+    }
+
+    checkConsistency();
+
+    if (i > MAX_ARRAY_INDEX)
+        return deleteProperty(exec, Identifier::from(exec, i));
+
+    return false;
+}
+
+void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+{
+    // FIXME: Filling PropertyNameArray with an identifier for every integer
+    // is incredibly inefficient for large arrays. We need a different approach,
+    // which almost certainly means a different structure for PropertyNameArray.
+
+    ArrayStorage* storage = m_storage;
+
+    unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
+    for (unsigned i = 0; i < usedVectorLength; ++i) {
+        if (storage->m_vector[i])
+            propertyNames.add(Identifier::from(exec, i));
+    }
+
+    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+        SparseArrayValueMap::iterator end = map->end();
+        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
+            propertyNames.add(Identifier::from(exec, it->first));
+    }
+
+    JSObject::getPropertyNames(exec, propertyNames);
+}
+
+bool JSArray::increaseVectorLength(unsigned newLength)
+{
+    // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
+    // to the vector. Callers have to account for that, because they can do it more efficiently.
+
+    ArrayStorage* storage = m_storage;
+
+    unsigned vectorLength = storage->m_vectorLength;
+    ASSERT(newLength > vectorLength);
+    ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX);
+    unsigned newVectorLength = increasedVectorLength(newLength);
+
+    storage = static_cast<ArrayStorage*>(tryFastRealloc(storage, storageSize(newVectorLength)));
+    if (!storage)
+        return false;
+
+    storage->m_vectorLength = newVectorLength;
+
+    for (unsigned i = vectorLength; i < newVectorLength; ++i)
+        storage->m_vector[i] = noValue();
+
+    m_storage = storage;
+    return true;
+}
+
+void JSArray::setLength(unsigned newLength)
+{
+    checkConsistency();
+
+    ArrayStorage* storage = m_storage;
+
+    unsigned length = m_storage->m_length;
+
+    if (newLength < length) {
+        if (m_fastAccessCutoff > newLength)
+            m_fastAccessCutoff = newLength;
+
+        unsigned usedVectorLength = min(length, storage->m_vectorLength);
+        for (unsigned i = newLength; i < usedVectorLength; ++i) {
+            JSValue*& valueSlot = storage->m_vector[i];
+            bool hadValue = valueSlot;
+            valueSlot = noValue();
+            storage->m_numValuesInVector -= hadValue;
+        }
+
+        if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+            SparseArrayValueMap copy = *map;
+            SparseArrayValueMap::iterator end = copy.end();
+            for (SparseArrayValueMap::iterator it = copy.begin(); it != end; ++it) {
+                if (it->first >= newLength)
+                    map->remove(it->first);
+            }
+            if (map->isEmpty()) {
+                delete map;
+                storage->m_sparseValueMap = 0;
+            }
+        }
+    }
+
+    m_storage->m_length = newLength;
+
+    checkConsistency();
+}
+
+JSValue* JSArray::pop()
+{
+    checkConsistency();
+
+    unsigned length = m_storage->m_length;
+    if (!length)
+        return jsUndefined();
+
+    --length;
+
+    JSValue* result;
+
+    if (m_fastAccessCutoff > length) {
+        JSValue*& valueSlot = m_storage->m_vector[length];
+        result = valueSlot;
+        ASSERT(result);
+        valueSlot = noValue();
+        --m_storage->m_numValuesInVector;
+        m_fastAccessCutoff = length;
+    } else if (length < m_storage->m_vectorLength) {
+        JSValue*& valueSlot = m_storage->m_vector[length];
+        result = valueSlot;
+        valueSlot = noValue();
+        if (result)
+            --m_storage->m_numValuesInVector;
+        else
+            result = jsUndefined();
+    } else {
+        result = jsUndefined();
+        if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
+            SparseArrayValueMap::iterator it = map->find(length);
+            if (it != map->end()) {
+                result = it->second;
+                map->remove(it);
+                if (map->isEmpty()) {
+                    delete map;
+                    m_storage->m_sparseValueMap = 0;
+                }
+            }
+        }
+    }
+
+    m_storage->m_length = length;
+
+    checkConsistency();
+
+    return result;
+}
+
+void JSArray::push(ExecState* exec, JSValue* value)
+{
+    checkConsistency();
+
+    if (m_storage->m_length < m_storage->m_vectorLength) {
+        ASSERT(!m_storage->m_vector[m_storage->m_length]);
+        m_storage->m_vector[m_storage->m_length] = value;
+        if (++m_storage->m_numValuesInVector == ++m_storage->m_length)
+            m_fastAccessCutoff = m_storage->m_length;
+        checkConsistency();
+        return;
+    }
+
+    if (m_storage->m_length < MIN_SPARSE_ARRAY_INDEX) {
+        SparseArrayValueMap* map = m_storage->m_sparseValueMap;
+        if (!map || map->isEmpty()) {
+            if (increaseVectorLength(m_storage->m_length + 1)) {
+                m_storage->m_vector[m_storage->m_length] = value;
+                if (++m_storage->m_numValuesInVector == ++m_storage->m_length)
+                    m_fastAccessCutoff = m_storage->m_length;
+                checkConsistency();
+                return;
+            }
+            checkConsistency();
+            throwOutOfMemoryError(exec);
+            return;
+        }
+    }
+
+    putSlowCase(exec, m_storage->m_length++, value);
+}
+
+void JSArray::mark()
+{
+    JSObject::mark();
+
+    ArrayStorage* storage = m_storage;
+
+    unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
+    for (unsigned i = 0; i < usedVectorLength; ++i) {
+        JSValue* value = storage->m_vector[i];
+        if (value && !value->marked())
+            value->mark();
+    }
+
+    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+        SparseArrayValueMap::iterator end = map->end();
+        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
+            JSValue* value = it->second;
+            if (!value->marked())
+                value->mark();
+        }
+    }
+}
+
+typedef std::pair<JSValue*, UString> ArrayQSortPair;
+
+static int compareByStringPairForQSort(const void* a, const void* b)
+{
+    const ArrayQSortPair* va = static_cast<const ArrayQSortPair*>(a);
+    const ArrayQSortPair* vb = static_cast<const ArrayQSortPair*>(b);
+    return compare(va->second, vb->second);
+}
+
+void JSArray::sort(ExecState* exec)
+{
+    unsigned lengthNotIncludingUndefined = compactForSorting();
+    if (m_storage->m_sparseValueMap) {
+        throwOutOfMemoryError(exec);
+        return;
+    }
+
+    if (!lengthNotIncludingUndefined)
+        return;
+
+    // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that.
+    // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary
+    // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
+    // random or otherwise changing results, effectively making compare function inconsistent.
+
+    Vector<ArrayQSortPair> values(lengthNotIncludingUndefined);
+    if (!values.begin()) {
+        throwOutOfMemoryError(exec);
+        return;
+    }
+
+    for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
+        JSValue* value = m_storage->m_vector[i];
+        ASSERT(!value->isUndefined());
+        values[i].first = value;
+    }
+
+    // FIXME: While calling these toString functions, the array could be mutated.
+    // In that case, objects pointed to by values in this vector might get garbage-collected!
+
+    // FIXME: The following loop continues to call toString on subsequent values even after
+    // a toString call raises an exception.
+
+    for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
+        values[i].second = values[i].first->toString(exec);
+
+    if (exec->hadException())
+        return;
+
+    // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather
+    // than O(N log N).
+
+#if HAVE(MERGESORT)
+    mergesort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
+#else
+    // FIXME: The qsort library function is likely to not be a stable sort.
+    // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort.
+    qsort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
+#endif
+
+    // FIXME: If the toString function changed the length of the array, this might be
+    // modifying the vector incorrectly.
+
+    for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
+        m_storage->m_vector[i] = values[i].first;
+
+    checkConsistency(SortConsistencyCheck);
+}
+
+struct AVLTreeNodeForArrayCompare {
+    JSValue* value;
+
+    // Child pointers.  The high bit of gt is robbed and used as the
+    // balance factor sign.  The high bit of lt is robbed and used as
+    // the magnitude of the balance factor.
+    int32_t gt;
+    int32_t lt;
+};
+
+struct AVLTreeAbstractorForArrayCompare {
+    typedef int32_t handle; // Handle is an index into m_nodes vector.
+    typedef JSValue* key;
+    typedef int32_t size;
+
+    Vector<AVLTreeNodeForArrayCompare> m_nodes;
+    ExecState* m_exec;
+    JSValue* m_compareFunction;
+    CallType m_compareCallType;
+    const CallData* m_compareCallData;
+    JSValue* m_globalThisValue;
+
+    handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
+    void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; }
+    handle get_greater(handle h) { return m_nodes[h].gt & 0x7FFFFFFF; }
+    void set_greater(handle h, handle gh) { m_nodes[h].gt &= 0x80000000; m_nodes[h].gt |= gh; }
+
+    int get_balance_factor(handle h)
+    {
+        if (m_nodes[h].gt & 0x80000000)
+            return -1;
+        return static_cast<unsigned>(m_nodes[h].lt) >> 31;
+    }
+
+    void set_balance_factor(handle h, int bf)
+    {
+        if (bf == 0) {
+            m_nodes[h].lt &= 0x7FFFFFFF;
+            m_nodes[h].gt &= 0x7FFFFFFF;
+        } else {
+            m_nodes[h].lt |= 0x80000000;
+            if (bf < 0)
+                m_nodes[h].gt |= 0x80000000;
+            else
+                m_nodes[h].gt &= 0x7FFFFFFF;
+        }
+    }
+
+    int compare_key_key(key va, key vb)
+    {
+        ASSERT(!va->isUndefined());
+        ASSERT(!vb->isUndefined());
+
+        if (m_exec->hadException())
+            return 1;
+
+        ArgList arguments;
+        arguments.append(va);
+        arguments.append(vb);
+        double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments)->toNumber(m_exec);
+        return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
+    }
+
+    int compare_key_node(key k, handle h) { return compare_key_key(k, m_nodes[h].value); }
+    int compare_node_node(handle h1, handle h2) { return compare_key_key(m_nodes[h1].value, m_nodes[h2].value); }
+
+    static handle null() { return 0x7FFFFFFF; }
+};
+
+void JSArray::sort(ExecState* exec, JSValue* compareFunction, CallType callType, const CallData& callData)
+{
+    checkConsistency();
+
+    // FIXME: This ignores exceptions raised in the compare function or in toNumber.
+
+    // The maximum tree depth is compiled in - but the caller is clearly up to no good
+    // if a larger array is passed.
+    ASSERT(m_storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max()));
+    if (m_storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
+        return;
+
+    if (!m_storage->m_length)
+        return;
+
+    unsigned usedVectorLength = min(m_storage->m_length, m_storage->m_vectorLength);
+
+    AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
+    tree.abstractor().m_exec = exec;
+    tree.abstractor().m_compareFunction = compareFunction;
+    tree.abstractor().m_compareCallType = callType;
+    tree.abstractor().m_compareCallData = &callData;
+    tree.abstractor().m_globalThisValue = exec->globalThisValue();
+    tree.abstractor().m_nodes.resize(usedVectorLength + (m_storage->m_sparseValueMap ? m_storage->m_sparseValueMap->size() : 0));
+
+    if (!tree.abstractor().m_nodes.begin()) {
+        throwOutOfMemoryError(exec);
+        return;
+    }
+
+    // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified
+    // right out from under us while we're building the tree here.
+
+    unsigned numDefined = 0;
+    unsigned numUndefined = 0;
+
+    // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
+    for (; numDefined < usedVectorLength; ++numDefined) {
+        JSValue* v = m_storage->m_vector[numDefined];
+        if (!v || v->isUndefined())
+            break;
+        tree.abstractor().m_nodes[numDefined].value = v;
+        tree.insert(numDefined);
+    }
+    for (unsigned i = numDefined; i < usedVectorLength; ++i) {
+        if (JSValue* v = m_storage->m_vector[i]) {
+            if (v->isUndefined())
+                ++numUndefined;
+            else {
+                tree.abstractor().m_nodes[numDefined].value = v;
+                tree.insert(numDefined);
+                ++numDefined;
+            }
+        }
+    }
+
+    unsigned newUsedVectorLength = numDefined + numUndefined;
+
+    if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
+        newUsedVectorLength += map->size();
+        if (newUsedVectorLength > m_storage->m_vectorLength) {
+            // Check that it is possible to allocate an array large enough to hold all the entries.
+            if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) {
+                throwOutOfMemoryError(exec);
+                return;
+            }
+        }
+
+        SparseArrayValueMap::iterator end = map->end();
+        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
+            tree.abstractor().m_nodes[numDefined].value = it->second;
+            tree.insert(numDefined);
+            ++numDefined;
+        }
+
+        delete map;
+        m_storage->m_sparseValueMap = 0;
+    }
+
+    ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
+
+    // FIXME: If the compare function changed the length of the array, the following might be
+    // modifying the vector incorrectly.
+
+    // Copy the values back into m_storage.
+    AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
+    iter.start_iter_least(tree);
+    for (unsigned i = 0; i < numDefined; ++i) {
+        m_storage->m_vector[i] = tree.abstractor().m_nodes[*iter].value;
+        ++iter;
+    }
+
+    // Put undefined values back in.
+    for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
+        m_storage->m_vector[i] = jsUndefined();
+
+    // Ensure that unused values in the vector are zeroed out.
+    for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
+        m_storage->m_vector[i] = noValue();
+
+    m_fastAccessCutoff = newUsedVectorLength;
+    m_storage->m_numValuesInVector = newUsedVectorLength;
+
+    checkConsistency(SortConsistencyCheck);
+}
+
+void JSArray::fillArgList(ExecState* exec, ArgList& args)
+{
+    unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff);
+    unsigned i = 0;
+    for (; i < fastAccessLength; ++i)
+        args.append(getIndex(i));
+    for (; i < m_storage->m_length; ++i)
+        args.append(get(exec, i));
+}
+
+unsigned JSArray::compactForSorting()
+{
+    checkConsistency();
+
+    ArrayStorage* storage = m_storage;
+
+    unsigned usedVectorLength = min(m_storage->m_length, storage->m_vectorLength);
+
+    unsigned numDefined = 0;
+    unsigned numUndefined = 0;
+
+    for (; numDefined < usedVectorLength; ++numDefined) {
+        JSValue* v = storage->m_vector[numDefined];
+        if (!v || v->isUndefined())
+            break;
+    }
+    for (unsigned i = numDefined; i < usedVectorLength; ++i) {
+        if (JSValue* v = storage->m_vector[i]) {
+            if (v->isUndefined())
+                ++numUndefined;
+            else
+                storage->m_vector[numDefined++] = v;
+        }
+    }
+
+    unsigned newUsedVectorLength = numDefined + numUndefined;
+
+    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+        newUsedVectorLength += map->size();
+        if (newUsedVectorLength > storage->m_vectorLength) {
+            // Check that it is possible to allocate an array large enough to hold all the entries - if not,
+            // exception is thrown by caller.
+            if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength))
+                return 0;
+            storage = m_storage;
+        }
+
+        SparseArrayValueMap::iterator end = map->end();
+        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
+            storage->m_vector[numDefined++] = it->second;
+
+        delete map;
+        storage->m_sparseValueMap = 0;
+    }
+
+    for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
+        storage->m_vector[i] = jsUndefined();
+    for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
+        storage->m_vector[i] = noValue();
+
+    m_fastAccessCutoff = newUsedVectorLength;
+    storage->m_numValuesInVector = newUsedVectorLength;
+
+    checkConsistency(SortConsistencyCheck);
+
+    return numDefined;
+}
+
+void* JSArray::lazyCreationData()
+{
+    return m_storage->lazyCreationData;
+}
+
+void JSArray::setLazyCreationData(void* d)
+{
+    m_storage->lazyCreationData = d;
+}
+
+#if CHECK_ARRAY_CONSISTENCY
+
+void JSArray::checkConsistency(ConsistencyCheckType type)
+{
+    ASSERT(m_storage);
+    if (type == SortConsistencyCheck)
+        ASSERT(!m_storage->m_sparseValueMap);
+
+    ASSERT(m_fastAccessCutoff <= m_storage->m_length);
+    ASSERT(m_fastAccessCutoff <= m_storage->m_numValuesInVector);
+
+    unsigned numValuesInVector = 0;
+    for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) {
+        if (JSValue* value = m_storage->m_vector[i]) {
+            ASSERT(i < m_storage->m_length);
+            if (type != DestructorConsistencyCheck)
+                value->type(); // Likely to crash if the object was deallocated.
+            ++numValuesInVector;
+        } else {
+            ASSERT(i >= m_fastAccessCutoff);
+            if (type == SortConsistencyCheck)
+                ASSERT(i >= m_storage->m_numValuesInVector);
+        }
+    }
+    ASSERT(numValuesInVector == m_storage->m_numValuesInVector);
+
+    if (m_storage->m_sparseValueMap) {
+        SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end();
+        for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) {
+            unsigned index = it->first;
+            ASSERT(index < m_storage->m_length);
+            ASSERT(index >= m_storage->m_vectorLength);
+            ASSERT(index <= MAX_ARRAY_INDEX);
+            ASSERT(it->second);
+            if (type != DestructorConsistencyCheck)
+                it->second->type(); // Likely to crash if the object was deallocated.
+        }
+    }
+}
+
+#endif
+
+JSArray* constructEmptyArray(ExecState* exec)
+{
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
+}
+
+JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
+{
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+}
+
+JSArray* constructArray(ExecState* exec, JSValue* singleItemValue)
+{
+    ArgList values;
+    values.append(singleItemValue);
+    return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
+}
+
+JSArray* constructArray(ExecState* exec, const ArgList& values)
+{
+    return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
new file mode 100644
index 0000000..165fafd
--- /dev/null
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -0,0 +1,126 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef JSArray_h
+#define JSArray_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    typedef HashMap<unsigned, JSValue*> SparseArrayValueMap;
+
+    struct ArrayStorage {
+        unsigned m_length;
+        unsigned m_vectorLength;
+        unsigned m_numValuesInVector;
+        SparseArrayValueMap* m_sparseValueMap;
+        void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
+        JSValue* m_vector[1];
+    };
+
+    class JSArray : public JSObject {
+        friend class CTI;
+
+    public:
+        explicit JSArray(PassRefPtr<StructureID>);
+        JSArray(PassRefPtr<StructureID>, unsigned initialLength);
+        JSArray(ExecState*, PassRefPtr<StructureID>, const ArgList& initialValues);
+        virtual ~JSArray();
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue*); // FIXME: Make protected and add setItem.
+
+        static const ClassInfo info;
+
+        unsigned length() const { return m_storage->m_length; }
+        void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray.
+
+        void sort(ExecState*);
+        void sort(ExecState*, JSValue* compareFunction, CallType, const CallData&);
+
+        void push(ExecState*, JSValue*);
+        JSValue* pop();
+
+        bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; }
+        JSValue* getIndex(unsigned i)
+        {
+            ASSERT(canGetIndex(i));
+            return m_storage->m_vector[i];
+        }
+
+        bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; }
+        JSValue* setIndex(unsigned i, JSValue* v)
+        {
+            ASSERT(canSetIndex(i));
+            return m_storage->m_vector[i] = v;
+        }
+
+        void fillArgList(ExecState*, ArgList&);
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+
+    protected:
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+        virtual bool deleteProperty(ExecState*, unsigned propertyName);
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+        virtual void mark();
+
+        void* lazyCreationData();
+        void setLazyCreationData(void*);
+
+    private:
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
+        void putSlowCase(ExecState*, unsigned propertyName, JSValue*);
+
+        bool increaseVectorLength(unsigned newLength);
+        
+        unsigned compactForSorting();
+
+        enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck };
+        void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck);
+
+        unsigned m_fastAccessCutoff;
+        ArrayStorage* m_storage;
+    };
+
+    JSArray* asArray(JSValue*);
+
+    JSArray* constructEmptyArray(ExecState*);
+    JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
+    JSArray* constructArray(ExecState*, JSValue* singleItemValue);
+    JSArray* constructArray(ExecState*, const ArgList& values);
+
+    inline JSArray* asArray(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&JSArray::info));
+        return static_cast<JSArray*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // JSArray_h
diff --git a/JavaScriptCore/runtime/JSCell.cpp b/JavaScriptCore/runtime/JSCell.cpp
new file mode 100644
index 0000000..cfe2f72
--- /dev/null
+++ b/JavaScriptCore/runtime/JSCell.cpp
@@ -0,0 +1,223 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSCell.h"
+
+#include "JSFunction.h"
+#include "JSString.h"
+#include "JSObject.h"
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+#if defined NAN && defined INFINITY
+
+extern const double NaN = NAN;
+extern const double Inf = INFINITY;
+
+#else // !(defined NAN && defined INFINITY)
+
+// The trick is to define the NaN and Inf globals with a different type than the declaration.
+// This trick works because the mangled name of the globals does not include the type, although
+// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of
+// characters don't necessarily need the same alignment doubles do, but for now it seems to work.
+// It would be good to figure out a 100% clean way that still avoids code that runs at init time.
+
+// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere,
+// while NaN_double has to be 4-byte aligned for 32-bits.
+// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading.
+
+static const union {
+    struct {
+        unsigned char NaN_Bytes[8];
+        unsigned char Inf_Bytes[8];
+    } bytes;
+    
+    struct {
+        double NaN_Double;
+        double Inf_Double;
+    } doubles;
+    
+} NaNInf = { {
+#if PLATFORM(BIG_ENDIAN)
+    { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 },
+    { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
+#elif PLATFORM(MIDDLE_ENDIAN)
+    { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 },
+    { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
+#else
+    { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f },
+    { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
+#endif
+} } ;
+
+extern const double NaN = NaNInf.doubles.NaN_Double;
+extern const double Inf = NaNInf.doubles.Inf_Double;
+ 
+#endif // !(defined NAN && defined INFINITY)
+
+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
+{
+    return false;
+}
+
+bool JSCell::getTruncatedInt32(int32_t&) const
+{
+    return false;
+}
+
+bool JSCell::getTruncatedUInt32(uint32_t&) const
+{
+    return false;
+}
+
+bool JSCell::getNumber(double& numericValue) const
+{
+    if (!isNumber())
+        return false;
+    numericValue = static_cast<const JSNumberCell*>(this)->value();
+    return true;
+}
+
+double JSCell::getNumber() const
+{
+    return isNumber() ? static_cast<const JSNumberCell*>(this)->value() : NaN;
+}
+
+bool JSCell::getString(UString&stringValue) const
+{
+    if (!isString())
+        return false;
+    stringValue = static_cast<const JSString*>(this)->value();
+    return true;
+}
+
+UString JSCell::getString() const
+{
+    return isString() ? static_cast<const JSString*>(this)->value() : UString();
+}
+
+JSObject* JSCell::getObject()
+{
+    return isObject() ? static_cast<JSObject*>(this) : 0;
+}
+
+const JSObject* JSCell::getObject() const
+{
+    return isObject() ? static_cast<const JSObject*>(this) : 0;
+}
+
+CallType JSCell::getCallData(CallData&)
+{
+    return CallTypeNone;
+}
+
+ConstructType JSCell::getConstructData(ConstructData&)
+{
+    return ConstructTypeNone;
+}
+
+bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot)
+{
+    // This is not a general purpose implementation of getOwnPropertySlot.
+    // It should only be called by JSValue::get.
+    // It calls getPropertySlot, not getOwnPropertySlot.
+    JSObject* object = toObject(exec);
+    slot.setBase(object);
+    if (!object->getPropertySlot(exec, identifier, slot))
+        slot.setUndefined();
+    return true;
+}
+
+bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot)
+{
+    // This is not a general purpose implementation of getOwnPropertySlot.
+    // It should only be called by JSValue::get.
+    // It calls getPropertySlot, not getOwnPropertySlot.
+    JSObject* object = toObject(exec);
+    slot.setBase(object);
+    if (!object->getPropertySlot(exec, identifier, slot))
+        slot.setUndefined();
+    return true;
+}
+
+void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value, PutPropertySlot& slot)
+{
+    toObject(exec)->put(exec, identifier, value, slot);
+}
+
+void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)
+{
+    toObject(exec)->put(exec, identifier, value);
+}
+
+bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
+{
+    return toObject(exec)->deleteProperty(exec, identifier);
+}
+
+bool JSCell::deleteProperty(ExecState* exec, unsigned identifier)
+{
+    return toObject(exec)->deleteProperty(exec, identifier);
+}
+
+JSObject* JSCell::toThisObject(ExecState* exec) const
+{
+    return toObject(exec);
+}
+
+UString JSCell::toThisString(ExecState* exec) const
+{
+    return toThisObject(exec)->toString(exec);
+}
+
+JSString* JSCell::toThisJSString(ExecState* exec)
+{
+    return jsString(exec, toThisString(exec));
+}
+
+const ClassInfo* JSCell::classInfo() const
+{
+    return 0;
+}
+
+JSValue* JSCell::getJSNumber()
+{
+    return noValue();
+}
+
+bool JSCell::isGetterSetter() const
+{
+    return false;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
new file mode 100644
index 0000000..108dab6
--- /dev/null
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -0,0 +1,311 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSCell_h
+#define JSCell_h
+
+#include "StructureID.h"
+#include "JSValue.h"
+#include "collector.h"
+
+namespace JSC {
+
+    class JSCell : public JSValue {
+        friend class CTI;
+        friend class GetterSetter;
+        friend class Heap;
+        friend class JSNumberCell;
+        friend class JSObject;
+        friend class JSPropertyNameIterator;
+        friend class JSString;
+        friend class JSValue;
+        friend class Machine;
+
+    private:
+        explicit JSCell(StructureID*);
+        virtual ~JSCell();
+
+    public:
+        // Querying the type.
+        bool isNumber() const;
+        bool isString() const;
+        bool isObject() const;
+        virtual bool isGetterSetter() const;
+        virtual bool isObject(const ClassInfo*) const;
+
+        StructureID* structureID() const;
+
+        // Extracting the value.
+        bool getNumber(double&) const;
+        double getNumber() const; // NaN if not a number
+        bool getString(UString&) const;
+        UString getString() const; // null string if not a string
+        JSObject* getObject(); // NULL if not an object
+        const JSObject* getObject() const; // NULL if not an object
+        
+        virtual CallType getCallData(CallData&);
+        virtual ConstructType getConstructData(ConstructData&);
+
+        // Extracting integer values.
+        virtual bool getUInt32(uint32_t&) const;
+        virtual bool getTruncatedInt32(int32_t&) const;
+        virtual bool getTruncatedUInt32(uint32_t&) const;
+
+        // Basic conversions.
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;
+        virtual bool toBoolean(ExecState*) const = 0;
+        virtual double toNumber(ExecState*) const = 0;
+        virtual UString toString(ExecState*) const = 0;
+        virtual JSObject* toObject(ExecState*) const = 0;
+
+        // Garbage collection.
+        void* operator new(size_t, ExecState*);
+        void* operator new(size_t, JSGlobalData*);
+        void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
+        virtual void mark();
+        bool marked() const;
+
+        // Object operations, with the toObject operation included.
+        virtual const ClassInfo* classInfo() const;
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue*);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+        virtual bool deleteProperty(ExecState*, unsigned propertyName);
+
+        virtual JSObject* toThisObject(ExecState*) const;
+        virtual UString toThisString(ExecState*) const;
+        virtual JSString* toThisJSString(ExecState*);
+        virtual JSValue* getJSNumber();
+        void* vptr() { return *reinterpret_cast<void**>(this); }
+
+    private:
+        // Base implementation; for non-object classes implements getPropertySlot.
+        bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+        
+        StructureID* m_structureID;
+    };
+
+    JSCell* asCell(JSValue*);
+
+    inline JSCell* asCell(JSValue* value)
+    {
+        ASSERT(!JSImmediate::isImmediate(value));
+        return static_cast<JSCell*>(value);
+    }
+
+    inline JSCell::JSCell(StructureID* structureID)
+        : m_structureID(structureID)
+    {
+    }
+
+    inline JSCell::~JSCell()
+    {
+    }
+
+    inline bool JSCell::isNumber() const
+    {
+        return Heap::isNumber(const_cast<JSCell*>(this));
+    }
+
+    inline bool JSCell::isObject() const
+    {
+        return m_structureID->typeInfo().type() == ObjectType;
+    }
+
+    inline bool JSCell::isString() const
+    {
+        return m_structureID->typeInfo().type() == StringType;
+    }
+
+    inline StructureID* JSCell::structureID() const
+    {
+        return m_structureID;
+    }
+
+    inline bool JSCell::marked() const
+    {
+        return Heap::isCellMarked(this);
+    }
+
+    inline void JSCell::mark()
+    {
+        return Heap::markCell(this);
+    }
+
+    ALWAYS_INLINE JSCell* JSValue::asCell() const
+    {
+        ASSERT(!JSImmediate::isImmediate(asValue()));
+        return reinterpret_cast<JSCell*>(const_cast<JSValue*>(this));
+    }
+
+    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 ----------------------------
+
+    inline bool JSValue::isNumber() const
+    {
+        return JSImmediate::isNumber(asValue()) || (!JSImmediate::isImmediate(asValue()) && asCell()->isNumber());
+    }
+
+    inline bool JSValue::isString() const
+    {
+        return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
+    }
+
+    inline bool JSValue::isGetterSetter() const
+    {
+        return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
+    }
+
+    inline bool JSValue::isObject() const
+    {
+        return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
+    }
+
+    inline double JSValue::getNumber() const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->getNumber();
+    }
+
+    inline bool JSValue::getString(UString& s) const
+    {
+        return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
+    }
+
+    inline UString JSValue::getString() const
+    {
+        return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
+    }
+
+    inline JSObject* JSValue::getObject() const
+    {
+        return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
+    }
+
+    inline CallType JSValue::getCallData(CallData& callData)
+    {
+        return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData);
+    }
+
+    inline ConstructType JSValue::getConstructData(ConstructData& constructData)
+    {
+        return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData);
+    }
+
+    ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v);
+    }
+
+    ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v);
+    }
+
+    inline bool JSValue::getTruncatedUInt32(uint32_t& v) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v);
+    }
+
+    inline void JSValue::mark()
+    {
+        asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
+    }
+
+    inline bool JSValue::marked() const
+    {
+        return JSImmediate::isImmediate(asValue()) || asCell()->marked();
+    }
+
+    inline JSValue* JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType);
+    }
+
+    inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
+    {
+        if (JSImmediate::isImmediate(asValue())) {
+            number = JSImmediate::toDouble(asValue());
+            value = asValue();
+            return true;
+        }
+        return asCell()->getPrimitiveNumber(exec, number, value);
+    }
+
+    inline bool JSValue::toBoolean(ExecState* exec) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec);
+    }
+
+    ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec);
+    }
+
+    inline UString JSValue::toString(ExecState* exec) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec);
+    }
+
+    inline JSObject* JSValue::toObject(ExecState* exec) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec);
+    }
+
+    inline JSObject* JSValue::toThisObject(ExecState* exec) const
+    {
+        if (UNLIKELY(JSImmediate::isImmediate(asValue())))
+            return JSImmediate::toObject(asValue(), exec);
+        return asCell()->toThisObject(exec);
+    }
+
+    inline bool JSValue::needsThisConversion() const
+    {
+        if (UNLIKELY(JSImmediate::isImmediate(asValue())))
+            return true;
+        return asCell()->structureID()->typeInfo().needsThisConversion();
+    }
+
+    inline UString JSValue::toThisString(ExecState* exec) const
+    {
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
+    }
+
+    inline JSValue* JSValue::getJSNumber()
+    {
+
+        return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();
+    }
+
+} // namespace JSC
+
+#endif // JSCell_h
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
new file mode 100644
index 0000000..2973d2d
--- /dev/null
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -0,0 +1,200 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSFunction.h"
+
+#include "CodeBlock.h"
+#include "CommonIdentifiers.h"
+#include "ExecState.h"
+#include "FunctionPrototype.h"
+#include "JSGlobalObject.h"
+#include "Machine.h"
+#include "ObjectPrototype.h"
+#include "Parser.h"
+#include "PropertyNameArray.h"
+#include "ScopeChainMark.h"
+
+using namespace WTF;
+using namespace Unicode;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSFunction);
+
+const ClassInfo JSFunction::info = { "Function", 0, 0, 0 };
+
+JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
+    : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
+    , m_body(body)
+    , m_scopeChain(scopeChainNode)
+{
+}
+
+JSFunction::~JSFunction()
+{
+#if ENABLE(CTI) 
+    // JIT code for other functions may have had calls linked directly to the code for this function; these links
+    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
+    // this memory is freed and may be reused (potentially for another, different JSFunction).
+    if (m_body.get() && m_body->isGenerated())
+        m_body->generatedByteCode().unlinkCallers();
+#endif
+}
+
+void JSFunction::mark()
+{
+    Base::mark();
+    m_body->mark();
+    m_scopeChain.mark();
+}
+
+CallType JSFunction::getCallData(CallData& callData)
+{
+    callData.js.functionBody = m_body.get();
+    callData.js.scopeChain = m_scopeChain.node();
+    return CallTypeJS;
+}
+
+JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
+{
+    return exec->machine()->execute(m_body.get(), exec, this, thisValue->toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
+}
+
+JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    JSFunction* thisObj = asFunction(slot.slotBase());
+    return exec->machine()->retrieveArguments(exec, thisObj);
+}
+
+JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    JSFunction* thisObj = asFunction(slot.slotBase());
+    return exec->machine()->retrieveCaller(exec, thisObj);
+}
+
+JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    JSFunction* thisObj = asFunction(slot.slotBase());
+    return jsNumber(exec, thisObj->m_body->parameterCount());
+}
+
+bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (propertyName == exec->propertyNames().prototype) {
+        JSValue** location = getDirectLocation(propertyName);
+
+        if (!location) {
+            JSObject* prototype = new (exec) JSObject(m_scopeChain.globalObject()->emptyObjectStructure());
+            prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
+            putDirect(exec->propertyNames().prototype, prototype, DontDelete);
+            location = getDirectLocation(propertyName);
+        }
+
+        slot.setValueSlot(this, location, offsetForLocation(location));
+    }
+
+    if (propertyName == exec->propertyNames().arguments) {
+        slot.setCustom(this, argumentsGetter);
+        return true;
+    }
+
+    if (propertyName == exec->propertyNames().length) {
+        slot.setCustom(this, lengthGetter);
+        return true;
+    }
+
+    if (propertyName == exec->propertyNames().caller) {
+        slot.setCustom(this, callerGetter);
+        return true;
+    }
+
+    return Base::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+        return;
+    Base::put(exec, propertyName, value, slot);
+}
+
+bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+        return false;
+    return Base::deleteProperty(exec, propertyName);
+}
+
+/* Returns the parameter name corresponding to the given index. eg:
+ * function f1(x, y, z): getParameterName(0) --> x
+ *
+ * If a name appears more than once, only the last index at which
+ * it appears associates with it. eg:
+ * function f2(x, x): getParameterName(0) --> null
+ */
+const Identifier& JSFunction::getParameterName(int index)
+{
+    const Identifier* parameters = m_body->parameters();
+
+    if (static_cast<size_t>(index) >= m_body->parameterCount())
+        return m_scopeChain.globalObject()->globalData()->propertyNames->nullIdentifier;
+  
+    const Identifier& name = parameters[index];
+
+    // Are there any subsequent parameters with the same name?
+    size_t size = m_body->parameterCount();
+    for (size_t i = index + 1; i < size; ++i) {
+        if (parameters[i] == name)
+            return m_scopeChain.globalObject()->globalData()->propertyNames->nullIdentifier;
+    }
+
+    return name;
+}
+
+// ECMA 13.2.2 [[Construct]]
+ConstructType JSFunction::getConstructData(ConstructData& constructData)
+{
+    constructData.js.functionBody = m_body.get();
+    constructData.js.scopeChain = m_scopeChain.node();
+    return ConstructTypeJS;
+}
+
+JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
+{
+    StructureID* structure;
+    JSValue* prototype = get(exec, exec->propertyNames().prototype);
+    if (prototype->isObject())
+        structure = asObject(prototype)->inheritorID();
+    else
+        structure = exec->lexicalGlobalObject()->emptyObjectStructure();
+    JSObject* thisObj = new (exec) JSObject(structure);
+
+    JSValue* result = exec->machine()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
+    if (exec->hadException() || !result->isObject())
+        return thisObj;
+    return asObject(result);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h
new file mode 100644
index 0000000..694a0f4
--- /dev/null
+++ b/JavaScriptCore/runtime/JSFunction.h
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSFunction_h
+#define JSFunction_h
+
+#include "InternalFunction.h"
+#include "JSVariableObject.h"
+#include "SymbolTable.h"
+#include "nodes.h"
+#include "JSObject.h"
+
+namespace JSC {
+
+    class FunctionBodyNode;
+    class FunctionPrototype;
+    class JSActivation;
+    class JSGlobalObject;
+
+    class JSFunction : public InternalFunction {
+        friend class CTI;
+        friend class Machine;
+
+        typedef InternalFunction Base;
+        JSFunction(PassRefPtr<JSC::StructureID> st) : InternalFunction(st), m_scopeChain(NoScopeChain()) {}
+    public:
+        JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
+        ~JSFunction();
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+
+        JSObject* construct(ExecState*, const ArgList&);
+        JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
+
+        // Note: Returns a null identifier for any parameters that will never get set
+        // due to a later parameter with the same name.
+        const Identifier& getParameterName(int index);
+
+        void setScope(const ScopeChain& scopeChain) { m_scopeChain = scopeChain; }
+        ScopeChain& scope() { return m_scopeChain; }
+
+        virtual void mark();
+
+        static const ClassInfo info;
+
+        // FIXME: This should be private
+        RefPtr<FunctionBodyNode> m_body;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype) 
+        { 
+            return StructureID::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); 
+        }
+
+    private:
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+
+        static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue* callerGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
+
+        ScopeChain m_scopeChain;
+    };
+
+    JSFunction* asFunction(JSValue*);
+
+    inline JSFunction* asFunction(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&JSFunction::info));
+        return static_cast<JSFunction*>(asObject(value));
+    }
+
+} // namespace kJS
+
+#endif // JSFunction_h
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
new file mode 100644
index 0000000..8910679
--- /dev/null
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGlobalData.h"
+
+#include "ArgList.h"
+#include "CommonIdentifiers.h"
+#include "JSActivation.h"
+#include "JSClassRef.h"
+#include "JSLock.h"
+#include "JSNotAnObject.h"
+#include "JSStaticScopeObject.h"
+#include "Machine.h"
+#include "Parser.h"
+#include "collector.h"
+#include "lexer.h"
+#include "lookup.h"
+#include "nodes.h"
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+#include <wtf/Threading.h>
+#endif
+
+#if PLATFORM(MAC)
+#include "ProfilerServer.h"
+#endif
+
+using namespace WTF;
+
+namespace JSC {
+
+extern const HashTable arrayTable;
+extern const HashTable dateTable;
+extern const HashTable mathTable;
+extern const HashTable numberTable;
+extern const HashTable regExpTable;
+extern const HashTable regExpConstructorTable;
+extern const HashTable stringTable;
+
+JSGlobalData::JSGlobalData(bool isShared)
+    : machine(new Machine)
+    , exception(noValue())
+    , arrayTable(new HashTable(JSC::arrayTable))
+    , dateTable(new HashTable(JSC::dateTable))
+    , mathTable(new HashTable(JSC::mathTable))
+    , numberTable(new HashTable(JSC::numberTable))
+    , regExpTable(new HashTable(JSC::regExpTable))
+    , regExpConstructorTable(new HashTable(JSC::regExpConstructorTable))
+    , stringTable(new HashTable(JSC::stringTable))
+    , activationStructureID(JSActivation::createStructureID(jsNull()))
+    , interruptedExecutionErrorStructure(JSObject::createStructureID(jsNull()))
+    , staticScopeStructureID(JSStaticScopeObject::createStructureID(jsNull()))
+    , stringStructureID(JSString::createStructureID(jsNull()))
+    , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructureID(jsNull()))
+    , notAnObjectStructure(JSNotAnObject::createStructureID(jsNull()))
+    , numberStructureID(JSNumberCell::createStructureID(jsNull()))
+    , identifierTable(createIdentifierTable())
+    , propertyNames(new CommonIdentifiers(this))
+    , emptyList(new ArgList)
+    , newParserObjects(0)
+    , parserObjectExtraRefCounts(0)
+    , lexer(new Lexer(this))
+    , parser(new Parser)
+    , head(0)
+    , dynamicGlobalObject(0)
+    , isSharedInstance(isShared)
+    , clientData(0)
+    , heap(this)
+{
+#if PLATFORM(MAC)
+    startProfilerServerIfNeeded();
+#endif
+}
+
+JSGlobalData::~JSGlobalData()
+{
+    // By the time this is destroyed, heap.destroy() must already have been called.
+
+    delete machine;
+#ifndef NDEBUG
+    // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
+    machine = 0;
+#endif
+
+    arrayTable->deleteTable();
+    dateTable->deleteTable();
+    mathTable->deleteTable();
+    numberTable->deleteTable();
+    regExpTable->deleteTable();
+    regExpConstructorTable->deleteTable();
+    stringTable->deleteTable();
+    delete arrayTable;
+    delete dateTable;
+    delete mathTable;
+    delete numberTable;
+    delete regExpTable;
+    delete regExpConstructorTable;
+    delete stringTable;
+
+    delete parser;
+    delete lexer;
+
+    deleteAllValues(opaqueJSClassData);
+
+    delete emptyList;
+
+    delete propertyNames;
+    deleteIdentifierTable(identifierTable);
+
+    delete newParserObjects;
+    delete parserObjectExtraRefCounts;
+    
+    delete clientData;
+}
+
+PassRefPtr<JSGlobalData> JSGlobalData::create()
+{
+    return adoptRef(new JSGlobalData);
+}
+
+PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
+{
+#ifndef NDEBUG
+    StructureID::startIgnoringLeaks();
+    RefPtr<JSGlobalData> data = create();
+    StructureID::stopIgnoringLeaks();
+    return data.release();
+#else
+    return create();
+#endif
+}
+
+bool JSGlobalData::sharedInstanceExists()
+{
+    return sharedInstanceInternal();
+}
+
+JSGlobalData& JSGlobalData::sharedInstance()
+{
+    JSGlobalData*& instance = sharedInstanceInternal();
+    if (!instance)
+        instance = new JSGlobalData(true);
+    return *instance;
+}
+
+JSGlobalData*& JSGlobalData::sharedInstanceInternal()
+{
+    ASSERT(JSLock::currentThreadIsHoldingLock());
+    static JSGlobalData* sharedInstance;
+    return sharedInstance;
+}
+
+JSGlobalData::ClientData::~ClientData()
+{
+}
+
+}
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
new file mode 100644
index 0000000..3210149
--- /dev/null
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 JSGlobalData_h
+#define JSGlobalData_h
+
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include "collector.h"
+#include "SmallStrings.h"
+
+struct OpaqueJSClass;
+struct OpaqueJSClassContextData;
+
+namespace JSC {
+
+    class ArgList;
+    class CommonIdentifiers;
+    class Heap;
+    class IdentifierTable;
+    class JSGlobalObject;
+    class JSObject;
+    class Lexer;
+    class Machine;
+    class Parser;
+    class ParserRefCounted;
+    class StructureID;
+    class UString;
+    struct HashTable;
+
+    class JSGlobalData : public RefCounted<JSGlobalData> {
+    public:
+        static bool sharedInstanceExists();
+        static JSGlobalData& sharedInstance();
+
+        static PassRefPtr<JSGlobalData> create();
+        static PassRefPtr<JSGlobalData> createLeaked();
+        ~JSGlobalData();
+
+        Machine* machine;
+
+        JSValue* exception;
+#if ENABLE(CTI)
+        void* throwReturnAddress;
+#endif
+
+        const HashTable* arrayTable;
+        const HashTable* dateTable;
+        const HashTable* mathTable;
+        const HashTable* numberTable;
+        const HashTable* regExpTable;
+        const HashTable* regExpConstructorTable;
+        const HashTable* stringTable;
+        
+        RefPtr<StructureID> activationStructureID;
+        RefPtr<StructureID> interruptedExecutionErrorStructure;
+        RefPtr<StructureID> staticScopeStructureID;
+        RefPtr<StructureID> stringStructureID;
+        RefPtr<StructureID> notAnObjectErrorStubStructure;
+        RefPtr<StructureID> notAnObjectStructure;
+        RefPtr<StructureID> numberStructureID;
+
+        IdentifierTable* identifierTable;
+        CommonIdentifiers* propertyNames;
+        const ArgList* 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;
+        
+        HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
+
+        HashSet<ParserRefCounted*>* newParserObjects;
+        HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
+
+        Lexer* lexer;
+        Parser* parser;
+
+        JSGlobalObject* head;
+        JSGlobalObject* dynamicGlobalObject;
+
+        bool isSharedInstance;
+
+        struct ClientData {
+            virtual ~ClientData() = 0;
+        };
+
+        ClientData* clientData;
+
+        HashSet<JSObject*> arrayVisitedElements;
+
+        Heap heap;
+
+    private:
+        JSGlobalData(bool isShared = false);
+
+        static JSGlobalData*& sharedInstanceInternal();
+    };
+
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
new file mode 100644
index 0000000..89c32fd
--- /dev/null
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGlobalObject.h"
+
+#include "JSCallbackConstructor.h"
+#include "JSCallbackFunction.h"
+#include "JSCallbackObject.h"
+
+#include "Arguments.h"
+#include "ArrayConstructor.h"
+#include "ArrayPrototype.h"
+#include "BooleanConstructor.h"
+#include "BooleanPrototype.h"
+#include "CodeBlock.h"
+#include "DateConstructor.h"
+#include "DatePrototype.h"
+#include "ErrorConstructor.h"
+#include "ErrorPrototype.h"
+#include "FunctionConstructor.h"
+#include "FunctionPrototype.h"
+#include "GlobalEvalFunction.h"
+#include "JSGlobalObjectFunctions.h"
+#include "JSLock.h"
+#include "Machine.h"
+#include "MathObject.h"
+#include "NativeErrorConstructor.h"
+#include "NativeErrorPrototype.h"
+#include "NumberConstructor.h"
+#include "NumberPrototype.h"
+#include "ObjectConstructor.h"
+#include "ObjectPrototype.h"
+#include "Profiler.h"
+#include "PrototypeFunction.h"
+#include "RegExpConstructor.h"
+#include "RegExpMatchesArray.h"
+#include "RegExpObject.h"
+#include "RegExpPrototype.h"
+#include "ScopeChainMark.h"
+#include "StringConstructor.h"
+#include "StringPrototype.h"
+#include "Debugger.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject);
+
+// Default number of ticks before a timeout check should be done.
+static const int initialTickCountThreshold = 255;
+
+// Preferred number of milliseconds between each timeout check
+static const int preferredScriptCheckTimeInterval = 1000;
+
+static inline void markIfNeeded(JSValue* v)
+{
+    if (v && !v->marked())
+        v->mark();
+}
+
+static inline void markIfNeeded(const RefPtr<StructureID>& s)
+{
+    if (s)
+        s->mark();
+}
+
+JSGlobalObject::~JSGlobalObject()
+{
+    ASSERT(JSLock::currentThreadIsHoldingLock());
+
+    if (d()->debugger)
+        d()->debugger->detach(this);
+
+    Profiler** profiler = Profiler::enabledProfilerReference();
+    if (UNLIKELY(*profiler != 0)) {
+        (*profiler)->stopProfiling(globalExec(), UString());
+    }
+
+    d()->next->d()->prev = d()->prev;
+    d()->prev->d()->next = d()->next;
+    JSGlobalObject*& headObject = head();
+    if (headObject == this)
+        headObject = d()->next;
+    if (headObject == this)
+        headObject = 0;
+
+    HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
+    for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+        (*it)->globalObject = 0;
+        
+    RegisterFile& registerFile = globalData()->machine->registerFile();
+    if (registerFile.globalObject() == this) {
+        registerFile.setGlobalObject(0);
+        registerFile.setNumGlobals(0);
+    }
+    delete d();
+}
+
+void JSGlobalObject::init(JSObject* thisValue)
+{
+    ASSERT(JSLock::currentThreadIsHoldingLock());
+
+    d()->globalData = Heap::heap(this)->globalData();
+    d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), thisValue);
+
+    JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.node(), CallFrame::noCaller(), 0, 0, 0);
+
+    if (JSGlobalObject*& headObject = head()) {
+        d()->prev = headObject;
+        d()->next = headObject->d()->next;
+        headObject->d()->next->d()->prev = this;
+        headObject->d()->next = this;
+    } else
+        headObject = d()->next = d()->prev = this;
+
+    d()->recursion = 0;
+    d()->debugger = 0;
+
+    d()->profileGroup = 0;
+
+    reset(prototype());
+}
+
+void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    if (symbolTablePut(propertyName, value))
+        return;
+    JSVariableObject::put(exec, propertyName, value, slot);
+}
+
+void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    if (symbolTablePutWithAttributes(propertyName, value, attributes))
+        return;
+
+    JSValue* valueBefore = getDirect(propertyName);
+    PutPropertySlot slot;
+    JSVariableObject::put(exec, propertyName, value, slot);
+    if (!valueBefore) {
+        if (JSValue* valueAfter = getDirect(propertyName))
+            putDirect(propertyName, valueAfter, attributes);
+    }
+}
+
+void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
+{
+    PropertySlot slot;
+    if (!symbolTableGet(propertyName, slot))
+        JSVariableObject::defineGetter(exec, propertyName, getterFunc);
+}
+
+void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
+{
+    PropertySlot slot;
+    if (!symbolTableGet(propertyName, slot))
+        JSVariableObject::defineSetter(exec, propertyName, setterFunc);
+}
+
+static inline JSObject* lastInPrototypeChain(JSObject* object)
+{
+    JSObject* o = object;
+    while (o->prototype()->isObject())
+        o = asObject(o->prototype());
+    return o;
+}
+
+void JSGlobalObject::reset(JSValue* prototype)
+{
+    ExecState* exec = JSGlobalObject::globalExec();
+
+    // Prototypes
+
+    d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructureID(jsNull())); // The real prototype will be set once ObjectPrototype is created.
+    d()->prototypeFunctionStructure = PrototypeFunction::createStructureID(d()->functionPrototype);
+    d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get());
+    d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructureID(jsNull()), d()->prototypeFunctionStructure.get());
+    d()->functionPrototype->structureID()->setPrototypeWithoutTransition(d()->objectPrototype);
+
+    d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
+
+    d()->functionStructure = JSFunction::createStructureID(d()->functionPrototype);
+    d()->callbackFunctionStructure = JSCallbackFunction::createStructureID(d()->functionPrototype);
+    d()->argumentsStructure = Arguments::createStructureID(d()->objectPrototype);
+    d()->callbackConstructorStructure = JSCallbackConstructor::createStructureID(d()->objectPrototype);
+    d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructureID(d()->objectPrototype);
+
+    d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructureID(d()->objectPrototype));
+    d()->arrayStructure = JSArray::createStructureID(d()->arrayPrototype);
+    d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructureID(d()->arrayPrototype);
+
+    d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructureID(d()->objectPrototype));
+    d()->stringObjectStructure = StringObject::createStructureID(d()->stringPrototype);
+
+    d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+    d()->booleanObjectStructure = BooleanObject::createStructureID(d()->booleanPrototype);
+
+    d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+    d()->numberObjectStructure = NumberObject::createStructureID(d()->numberPrototype);
+
+    d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructureID(d()->objectPrototype));
+    d()->dateStructure = DateInstance::createStructureID(d()->datePrototype);
+
+    d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+    d()->regExpStructure = RegExpObject::createStructureID(d()->regExpPrototype);
+
+    ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+    d()->errorStructure = ErrorInstance::createStructureID(errorPrototype);
+
+    RefPtr<StructureID> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructureID(errorPrototype);
+
+    NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError", "EvalError");
+    NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError", "RangeError");
+    NativeErrorPrototype* referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "ReferenceError", "ReferenceError");
+    NativeErrorPrototype* syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "SyntaxError", "SyntaxError");
+    NativeErrorPrototype* typeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "TypeError", "TypeError");
+    NativeErrorPrototype* URIErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "URIError", "URIError");
+
+    // Constructors
+
+    JSValue* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructureID(d()->functionPrototype), d()->objectPrototype);
+    JSValue* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructureID(d()->functionPrototype), d()->functionPrototype);
+    JSValue* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructureID(d()->functionPrototype), d()->arrayPrototype);
+    JSValue* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructureID(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
+    JSValue* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructureID(d()->functionPrototype), d()->booleanPrototype);
+    JSValue* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructureID(d()->functionPrototype), d()->numberPrototype);
+    JSValue* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructureID(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
+
+    d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructureID(d()->functionPrototype), d()->regExpPrototype);
+
+    d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructureID(d()->functionPrototype), errorPrototype);
+
+    RefPtr<StructureID> nativeErrorStructure = NativeErrorConstructor::createStructureID(d()->functionPrototype);
+
+    d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype);
+    d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype);
+    d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, referenceErrorPrototype);
+    d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype);
+    d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
+    d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
+
+    d()->objectPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
+    d()->functionPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
+    d()->arrayPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
+    d()->booleanPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
+    d()->stringPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
+    d()->numberPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
+    d()->datePrototype->putDirectWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
+    d()->regExpPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
+    errorPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
+
+    evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum);
+    rangeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->rangeErrorConstructor, DontEnum);
+    referenceErrorPrototype->putDirect(exec->propertyNames().constructor, d()->referenceErrorConstructor, DontEnum);
+    syntaxErrorPrototype->putDirect(exec->propertyNames().constructor, d()->syntaxErrorConstructor, DontEnum);
+    typeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->typeErrorConstructor, DontEnum);
+    URIErrorPrototype->putDirect(exec->propertyNames().constructor, d()->URIErrorConstructor, DontEnum);
+
+    // Set global constructors
+
+    // FIXME: These properties could be handled by a static hash table.
+
+    putDirectWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
+    putDirectWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
+    putDirectWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
+    putDirectWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
+    putDirectWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
+    putDirectWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
+    putDirectWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);
+
+    // Set global values.
+    GlobalPropertyInfo staticGlobals[] = {
+        GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructureID(d()->objectPrototype)), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete)
+    };
+
+    addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
+
+    // Set global functions.
+
+    d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructureID(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
+    putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+#ifndef NDEBUG
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
+#endif
+
+    resetPrototype(prototype);
+}
+
+// Set prototype, and also insert the object prototype at the end of the chain.
+void JSGlobalObject::resetPrototype(JSValue* prototype)
+{
+    setPrototype(prototype);
+    lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
+}
+
+void JSGlobalObject::setTimeoutTime(unsigned timeoutTime)
+{
+    globalData()->machine->setTimeoutTime(timeoutTime);
+}
+
+void JSGlobalObject::startTimeoutCheck()
+{
+    globalData()->machine->startTimeoutCheck();
+}
+
+void JSGlobalObject::stopTimeoutCheck()
+{
+    globalData()->machine->stopTimeoutCheck();
+}
+
+void JSGlobalObject::mark()
+{
+    JSVariableObject::mark();
+    
+    HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
+    for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+        (*it)->mark();
+
+    RegisterFile& registerFile = globalData()->machine->registerFile();
+    if (registerFile.globalObject() == this)
+        registerFile.markGlobals(&globalData()->heap);
+
+    markIfNeeded(d()->regExpConstructor);
+    markIfNeeded(d()->errorConstructor);
+    markIfNeeded(d()->evalErrorConstructor);
+    markIfNeeded(d()->rangeErrorConstructor);
+    markIfNeeded(d()->referenceErrorConstructor);
+    markIfNeeded(d()->syntaxErrorConstructor);
+    markIfNeeded(d()->typeErrorConstructor);
+    markIfNeeded(d()->URIErrorConstructor);
+
+    markIfNeeded(d()->evalFunction);
+
+    markIfNeeded(d()->objectPrototype);
+    markIfNeeded(d()->functionPrototype);
+    markIfNeeded(d()->arrayPrototype);
+    markIfNeeded(d()->booleanPrototype);
+    markIfNeeded(d()->stringPrototype);
+    markIfNeeded(d()->numberPrototype);
+    markIfNeeded(d()->datePrototype);
+    markIfNeeded(d()->regExpPrototype);
+
+    markIfNeeded(d()->errorStructure);
+
+    // No need to mark the other structures, because their prototypes are all
+    // guaranteed to be referenced elsewhere.
+
+    Register* registerArray = d()->registerArray.get();
+    if (!registerArray)
+        return;
+
+    size_t size = d()->registerArraySize;
+    for (size_t i = 0; i < size; ++i) {
+        Register& r = registerArray[i];
+        if (!r.marked())
+            r.mark();
+    }
+}
+
+void JSGlobalObject::markCrossHeapDependentObjects()
+{
+    // Overridden by subclasses.
+}
+
+JSGlobalObject* JSGlobalObject::toGlobalObject(ExecState*) const
+{
+    return const_cast<JSGlobalObject*>(this);
+}
+
+ExecState* JSGlobalObject::globalExec()
+{
+    return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
+}
+
+bool JSGlobalObject::isDynamicScope() const
+{
+    return true;
+}
+
+void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
+{
+    ASSERT(!d()->registerArray);
+    ASSERT(!d()->registerArraySize);
+
+    int numGlobals = registerFile.numGlobals();
+    if (!numGlobals) {
+        d()->registers = 0;
+        return;
+    }
+    
+    Register* registerArray = copyRegisterArray(registerFile.lastGlobal(), numGlobals);
+    setRegisters(registerArray + numGlobals, registerArray, numGlobals);
+}
+
+void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
+{
+    JSGlobalObject* lastGlobalObject = registerFile.globalObject();
+    if (lastGlobalObject && lastGlobalObject != this)
+        lastGlobalObject->copyGlobalsFrom(registerFile);
+
+    registerFile.setGlobalObject(this);
+    registerFile.setNumGlobals(symbolTable().size());
+
+    if (d()->registerArray) {
+        memcpy(registerFile.start() - d()->registerArraySize, d()->registerArray.get(), d()->registerArraySize * sizeof(Register));
+        setRegisters(registerFile.start(), 0, 0);
+    }
+}
+
+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
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
new file mode 100644
index 0000000..d8a072a
--- /dev/null
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -0,0 +1,363 @@
+/*
+ *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSGlobalObject_h
+#define JSGlobalObject_h
+
+#include "JSGlobalData.h"
+#include "JSVariableObject.h"
+#include "NumberPrototype.h"
+#include "StringPrototype.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
+namespace JSC {
+
+    class ArrayPrototype;
+    class BooleanPrototype;
+    class DatePrototype;
+    class Debugger;
+    class ErrorConstructor;
+    class FunctionPrototype;
+    class GlobalEvalFunction;
+    class NativeErrorConstructor;
+    class ProgramCodeBlock;
+    class RegExpConstructor;
+    class RegExpPrototype;
+    class RegisterFile;
+
+    struct ActivationStackNode;
+    struct HashTable;
+
+    typedef Vector<ExecState*, 16> ExecStateStack;
+
+    class JSGlobalObject : public JSVariableObject {
+    protected:
+        using JSVariableObject::JSVariableObjectData;
+
+        struct JSGlobalObjectData : public JSVariableObjectData {
+            JSGlobalObjectData()
+                : JSVariableObjectData(&symbolTable, 0)
+                , registerArraySize(0)
+                , globalScopeChain(NoScopeChain())
+                , regExpConstructor(0)
+                , errorConstructor(0)
+                , evalErrorConstructor(0)
+                , rangeErrorConstructor(0)
+                , referenceErrorConstructor(0)
+                , syntaxErrorConstructor(0)
+                , typeErrorConstructor(0)
+                , URIErrorConstructor(0)
+                , evalFunction(0)
+                , objectPrototype(0)
+                , functionPrototype(0)
+                , arrayPrototype(0)
+                , booleanPrototype(0)
+                , stringPrototype(0)
+                , numberPrototype(0)
+                , datePrototype(0)
+                , regExpPrototype(0)
+            {
+            }
+            
+            virtual ~JSGlobalObjectData()
+            {
+            }
+
+            size_t registerArraySize;
+
+            JSGlobalObject* next;
+            JSGlobalObject* prev;
+
+            Debugger* debugger;
+            
+            ScopeChain globalScopeChain;
+            Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
+
+            int recursion;
+
+            RegExpConstructor* regExpConstructor;
+            ErrorConstructor* errorConstructor;
+            NativeErrorConstructor* evalErrorConstructor;
+            NativeErrorConstructor* rangeErrorConstructor;
+            NativeErrorConstructor* referenceErrorConstructor;
+            NativeErrorConstructor* syntaxErrorConstructor;
+            NativeErrorConstructor* typeErrorConstructor;
+            NativeErrorConstructor* URIErrorConstructor;
+
+            GlobalEvalFunction* evalFunction;
+
+            ObjectPrototype* objectPrototype;
+            FunctionPrototype* functionPrototype;
+            ArrayPrototype* arrayPrototype;
+            BooleanPrototype* booleanPrototype;
+            StringPrototype* stringPrototype;
+            NumberPrototype* numberPrototype;
+            DatePrototype* datePrototype;
+            RegExpPrototype* regExpPrototype;
+
+            RefPtr<StructureID> argumentsStructure;
+            RefPtr<StructureID> arrayStructure;
+            RefPtr<StructureID> booleanObjectStructure;
+            RefPtr<StructureID> callbackConstructorStructure;
+            RefPtr<StructureID> callbackFunctionStructure;
+            RefPtr<StructureID> callbackObjectStructure;
+            RefPtr<StructureID> dateStructure;
+            RefPtr<StructureID> emptyObjectStructure;
+            RefPtr<StructureID> errorStructure;
+            RefPtr<StructureID> functionStructure;
+            RefPtr<StructureID> numberObjectStructure;
+            RefPtr<StructureID> prototypeFunctionStructure;
+            RefPtr<StructureID> regExpMatchesArrayStructure;
+            RefPtr<StructureID> regExpStructure;
+            RefPtr<StructureID> stringObjectStructure;
+
+            SymbolTable symbolTable;
+            unsigned profileGroup;
+
+            RefPtr<JSGlobalData> globalData;
+
+            HashSet<ProgramCodeBlock*> codeBlocks;
+        };
+
+    public:
+        void* operator new(size_t, JSGlobalData*);
+
+        explicit JSGlobalObject()
+            : JSVariableObject(JSGlobalObject::createStructureID(jsNull()), new JSGlobalObjectData)
+        {
+            init(this);
+        }
+
+    protected:
+        JSGlobalObject(PassRefPtr<StructureID> structure, JSGlobalObjectData* data, JSObject* thisValue)
+            : JSVariableObject(structure, data)
+        {
+            init(thisValue);
+        }
+
+    public:
+        virtual ~JSGlobalObject();
+
+        virtual void mark();
+        virtual void markCrossHeapDependentObjects();
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
+        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
+        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
+
+        virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
+        virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
+
+        // Linked list of all global objects that use the same JSGlobalData.
+        JSGlobalObject*& head() { return d()->globalData->head; }
+        JSGlobalObject* next() { return d()->next; }
+
+        // The following accessors return pristine values, even if a script 
+        // replaces the global object's associated property.
+
+        RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; }
+
+        ErrorConstructor* errorConstructor() const { return d()->errorConstructor; }
+        NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; }
+        NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
+        NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
+        NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
+        NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; }
+        NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; }
+
+        GlobalEvalFunction* evalFunction() const { return d()->evalFunction; }
+
+        ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
+        FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
+        ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
+        BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
+        StringPrototype* stringPrototype() const { return d()->stringPrototype; }
+        NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
+        DatePrototype* datePrototype() const { return d()->datePrototype; }
+        RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
+
+        StructureID* argumentsStructure() const { return d()->argumentsStructure.get(); }
+        StructureID* arrayStructure() const { return d()->arrayStructure.get(); }
+        StructureID* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
+        StructureID* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
+        StructureID* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
+        StructureID* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
+        StructureID* dateStructure() const { return d()->dateStructure.get(); }
+        StructureID* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
+        StructureID* errorStructure() const { return d()->errorStructure.get(); }
+        StructureID* functionStructure() const { return d()->functionStructure.get(); }
+        StructureID* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
+        StructureID* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
+        StructureID* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
+        StructureID* regExpStructure() const { return d()->regExpStructure.get(); }
+        StructureID* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
+
+        void setProfileGroup(unsigned value) { d()->profileGroup = value; }
+        unsigned profileGroup() const { return d()->profileGroup; }
+
+        void setTimeoutTime(unsigned timeoutTime);
+        void startTimeoutCheck();
+        void stopTimeoutCheck();
+
+        Debugger* debugger() const { return d()->debugger; }
+        void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
+        
+        virtual bool supportsProfiling() const { return false; }
+        
+        int recursion() { return d()->recursion; }
+        void incRecursion() { ++d()->recursion; }
+        void decRecursion() { --d()->recursion; }
+        
+        ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
+
+        virtual bool isGlobalObject() const { return true; }
+        virtual JSGlobalObject* toGlobalObject(ExecState*) const;
+
+        virtual ExecState* globalExec();
+
+        virtual bool shouldInterruptScript() const { return true; }
+
+        virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
+
+        virtual bool isDynamicScope() const;
+
+        HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
+
+        void copyGlobalsFrom(RegisterFile&);
+        void copyGlobalsTo(RegisterFile&);
+        
+        void resetPrototype(JSValue* prototype);
+
+        JSGlobalData* globalData() { return d()->globalData.get(); }
+        JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+
+    protected:
+        struct GlobalPropertyInfo {
+            GlobalPropertyInfo(const Identifier& i, JSValue* v, unsigned a)
+                : identifier(i)
+                , value(v)
+                , attributes(a)
+            {
+            }
+
+            const Identifier identifier;
+            JSValue* value;
+            unsigned attributes;
+        };
+        void addStaticGlobals(GlobalPropertyInfo*, int count);
+
+    private:
+        // FIXME: Fold reset into init.
+        void init(JSObject* thisValue);
+        void reset(JSValue* prototype);
+
+        void setRegisters(Register* registers, Register* registerArray, size_t count);
+
+        void* operator new(size_t); // can only be allocated with JSGlobalData
+    };
+
+    JSGlobalObject* asGlobalObject(JSValue*);
+
+    inline JSGlobalObject* asGlobalObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->isGlobalObject());
+        return static_cast<JSGlobalObject*>(asObject(value));
+    }
+
+    inline void JSGlobalObject::setRegisters(Register* registers, Register* registerArray, size_t count)
+    {
+        JSVariableObject::setRegisters(registers, registerArray);
+        d()->registerArraySize = count;
+    }
+
+    inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
+    {
+        size_t oldSize = d()->registerArraySize;
+        size_t newSize = oldSize + count;
+        Register* registerArray = new Register[newSize];
+        if (d()->registerArray)
+            memcpy(registerArray + count, d()->registerArray.get(), oldSize * sizeof(Register));
+        setRegisters(registerArray + newSize, registerArray, newSize);
+
+        for (int i = 0, index = -static_cast<int>(oldSize) - 1; i < count; ++i, --index) {
+            GlobalPropertyInfo& global = globals[i];
+            ASSERT(global.attributes & DontDelete);
+            SymbolTableEntry newEntry(index, global.attributes);
+            symbolTable().add(global.identifier.ustring().rep(), newEntry);
+            registerAt(index) = global.value;
+        }
+    }
+
+    inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+    {
+        if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
+            return true;
+        return symbolTableGet(propertyName, slot);
+    }
+
+    inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+    {
+        if (JSVariableObject::getOwnPropertySlotForWrite(exec, propertyName, slot, slotIsWriteable))
+            return true;
+        return symbolTableGet(propertyName, slot, slotIsWriteable);
+    }
+
+    inline JSGlobalObject* ScopeChainNode::globalObject() const
+    {
+        const ScopeChainNode* n = this;
+        while (n->next)
+            n = n->next;
+        return asGlobalObject(n->object);
+    }
+
+    inline JSValue* StructureID::prototypeForLookup(ExecState* exec)
+    {
+        if (typeInfo().type() == ObjectType)
+            return m_prototype;
+
+        if (typeInfo().type() == StringType)
+            return exec->lexicalGlobalObject()->stringPrototype();
+
+        ASSERT(typeInfo().type() == NumberType);
+        return exec->lexicalGlobalObject()->numberPrototype();
+    }
+
+    inline JSGlobalObject* ExecState::dynamicGlobalObject()
+    {
+        if (this == lexicalGlobalObject()->globalExec())
+            return lexicalGlobalObject();
+
+        // For any ExecState that's not a globalExec, the 
+        // dynamic global object must be set since code is running
+        ASSERT(globalData().dynamicGlobalObject);
+        return globalData().dynamicGlobalObject;
+    }
+    
+} // namespace JSC
+
+#endif // JSGlobalObject_h
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
new file mode 100644
index 0000000..8bb1c6b
--- /dev/null
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -0,0 +1,433 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSGlobalObjectFunctions.h"
+
+#include "ExecState.h"
+#include "GlobalEvalFunction.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+#include "Machine.h"
+#include "Parser.h"
+#include "dtoa.h"
+#include "lexer.h"
+#include "nodes.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/unicode/UTF8.h>
+
+using namespace WTF;
+using namespace Unicode;
+
+namespace JSC {
+
+static JSValue* encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
+{
+    UString str = args.at(exec, 0)->toString(exec);
+    CString cstr = str.UTF8String(true);
+    if (!cstr.c_str())
+        return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
+
+    UString result = "";
+    const char* p = cstr.c_str();
+    for (size_t k = 0; k < cstr.size(); k++, p++) {
+        char c = *p;
+        if (c && strchr(doNotEscape, c))
+            result.append(c);
+        else {
+            char tmp[4];
+            sprintf(tmp, "%%%02X", static_cast<unsigned char>(c));
+            result += tmp;
+        }
+    }
+    return jsString(exec, result);
+}
+
+static JSValue* decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
+{
+    UString result = "";
+    UString str = args.at(exec, 0)->toString(exec);
+    int k = 0;
+    int len = str.size();
+    const UChar* d = str.data();
+    UChar u = 0;
+    while (k < len) {
+        const UChar* p = d + k;
+        UChar c = *p;
+        if (c == '%') {
+            int charLen = 0;
+            if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) {
+                const char b0 = Lexer::convertHex(p[1], p[2]);
+                const int sequenceLen = UTF8SequenceLength(b0);
+                if (sequenceLen != 0 && k <= len - sequenceLen * 3) {
+                    charLen = sequenceLen * 3;
+                    char sequence[5];
+                    sequence[0] = b0;
+                    for (int i = 1; i < sequenceLen; ++i) {
+                        const UChar* q = p + i * 3;
+                        if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2]))
+                            sequence[i] = Lexer::convertHex(q[1], q[2]);
+                        else {
+                            charLen = 0;
+                            break;
+                        }
+                    }
+                    if (charLen != 0) {
+                        sequence[sequenceLen] = 0;
+                        const int character = decodeUTF8Sequence(sequence);
+                        if (character < 0 || character >= 0x110000)
+                            charLen = 0;
+                        else if (character >= 0x10000) {
+                            // Convert to surrogate pair.
+                            result.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
+                            u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
+                        } else
+                            u = static_cast<UChar>(character);
+                    }
+                }
+            }
+            if (charLen == 0) {
+                if (strict)
+                    return throwError(exec, URIError);
+                // The only case where we don't use "strict" mode is the "unescape" function.
+                // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE.
+                if (k <= len - 6 && p[1] == 'u'
+                        && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3])
+                        && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) {
+                    charLen = 6;
+                    u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]);
+                }
+            }
+            if (charLen && (u == 0 || u >= 128 || !strchr(doNotUnescape, u))) {
+                c = u;
+                k += charLen - 1;
+            }
+        }
+        k++;
+        result.append(c);
+    }
+    return jsString(exec, result);
+}
+
+bool isStrWhiteSpace(UChar c)
+{
+    switch (c) {
+        case 0x0009:
+        case 0x000A:
+        case 0x000B:
+        case 0x000C:
+        case 0x000D:
+        case 0x0020:
+        case 0x00A0:
+        case 0x2028:
+        case 0x2029:
+            return true;
+        default:
+            return c > 0xff && isSeparatorSpace(c);
+    }
+}
+
+static int parseDigit(unsigned short c, int radix)
+{
+    int digit = -1;
+
+    if (c >= '0' && c <= '9')
+        digit = c - '0';
+    else if (c >= 'A' && c <= 'Z')
+        digit = c - 'A' + 10;
+    else if (c >= 'a' && c <= 'z')
+        digit = c - 'a' + 10;
+
+    if (digit >= radix)
+        return -1;
+    return digit;
+}
+
+double parseIntOverflow(const char* s, int length, int radix)
+{
+    double number = 0.0;
+    double radixMultiplier = 1.0;
+
+    for (const char* p = s + length - 1; p >= s; p--) {
+        if (radixMultiplier == Inf) {
+            if (*p != '0') {
+                number = Inf;
+                break;
+            }
+        } else {
+            int digit = parseDigit(*p, radix);
+            number += digit * radixMultiplier;
+        }
+
+        radixMultiplier *= radix;
+    }
+
+    return number;
+}
+
+static double parseInt(const UString& s, int radix)
+{
+    int length = s.size();
+    const UChar* data = s.data();
+    int p = 0;
+
+    while (p < length && isStrWhiteSpace(data[p]))
+        ++p;
+
+    double sign = 1;
+    if (p < length) {
+        if (data[p] == '+')
+            ++p;
+        else if (data[p] == '-') {
+            sign = -1;
+            ++p;
+        }
+    }
+
+    if ((radix == 0 || radix == 16) && length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X')) {
+        radix = 16;
+        p += 2;
+    } else if (radix == 0) {
+        if (p < length && data[p] == '0')
+            radix = 8;
+        else
+            radix = 10;
+    }
+
+    if (radix < 2 || radix > 36)
+        return NaN;
+
+    int firstDigitPosition = p;
+    bool sawDigit = false;
+    double number = 0;
+    while (p < length) {
+        int digit = parseDigit(data[p], radix);
+        if (digit == -1)
+            break;
+        sawDigit = true;
+        number *= radix;
+        number += digit;
+        ++p;
+    }
+
+    if (number >= mantissaOverflowLowerBound) {
+        if (radix == 10)
+            number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
+        else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
+            number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
+    }
+
+    if (!sawDigit)
+        return NaN;
+
+    return sign * number;
+}
+
+static double parseFloat(const UString& s)
+{
+    // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0.
+    // Need to skip any whitespace and then one + or - sign.
+    int length = s.size();
+    const UChar* data = s.data();
+    int p = 0;
+    while (p < length && isStrWhiteSpace(data[p]))
+        ++p;
+
+    if (p < length && (data[p] == '+' || data[p] == '-'))
+        ++p;
+
+    if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X'))
+        return 0;
+
+    return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
+}
+
+JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObject = thisValue->toThisObject(exec);
+    JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
+    if (!globalObject || globalObject->evalFunction() != function)
+        return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
+
+    JSValue* x = args.at(exec, 0);
+    if (!x->isString())
+        return x;
+
+    UString s = x->toString(exec);
+
+    int errLine;
+    UString errMsg;
+
+    SourceCode source = makeSource(s);
+    RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
+
+    if (!evalNode)
+        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
+
+    return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
+}
+
+JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    JSValue* value = args.at(exec, 0);
+    int32_t radix = args.at(exec, 1)->toInt32(exec);
+
+    if (value->isNumber() && (radix == 0 || radix == 10)) {
+        if (JSImmediate::isImmediate(value))
+            return value;
+        double d = value->uncheckedGetNumber();
+        if (!isfinite(d))
+            return JSImmediate::zeroImmediate();
+        return jsNumber(exec, floor(d));
+    }
+
+    return jsNumber(exec, parseInt(value->toString(exec), radix));
+}
+
+JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, parseFloat(args.at(exec, 0)->toString(exec)));
+}
+
+JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsBoolean(isnan(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    double n = args.at(exec, 0)->toNumber(exec);
+    return jsBoolean(!isnan(n) && !isinf(n));
+}
+
+JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    static const char do_not_unescape_when_decoding_URI[] =
+        "#$&+,/:;=?@";
+
+    return decode(exec, args, do_not_unescape_when_decoding_URI, true);
+}
+
+JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return decode(exec, args, "", true);
+}
+
+JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    static const char do_not_escape_when_encoding_URI[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        "abcdefghijklmnopqrstuvwxyz"
+        "0123456789"
+        "!#$&'()*+,-./:;=?@_~";
+
+    return encode(exec, args, do_not_escape_when_encoding_URI);
+}
+
+JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    static const char do_not_escape_when_encoding_URI_component[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        "abcdefghijklmnopqrstuvwxyz"
+        "0123456789"
+        "!'()*-._~";
+
+    return encode(exec, args, do_not_escape_when_encoding_URI_component);
+}
+
+JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    static const char do_not_escape[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        "abcdefghijklmnopqrstuvwxyz"
+        "0123456789"
+        "*+-./@_";
+
+    UString result = "";
+    UString s;
+    UString str = args.at(exec, 0)->toString(exec);
+    const UChar* c = str.data();
+    for (int k = 0; k < str.size(); k++, c++) {
+        int u = c[0];
+        if (u > 255) {
+            char tmp[7];
+            sprintf(tmp, "%%u%04X", u);
+            s = UString(tmp);
+        } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u)))
+            s = UString(c, 1);
+        else {
+            char tmp[4];
+            sprintf(tmp, "%%%02X", u);
+            s = UString(tmp);
+        }
+        result += s;
+    }
+
+    return jsString(exec, result);
+}
+
+JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    UString result = "";
+    UString str = args.at(exec, 0)->toString(exec);
+    int k = 0;
+    int len = str.size();
+    while (k < len) {
+        const UChar* c = str.data() + k;
+        UChar u;
+        if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
+            if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
+                u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
+                c = &u;
+                k += 5;
+            }
+        } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
+            u = UChar(Lexer::convertHex(c[1], c[2]));
+            c = &u;
+            k += 2;
+        }
+        k++;
+        result.append(*c);
+    }
+
+    return jsString(exec, result);
+}
+
+#ifndef NDEBUG
+JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    CStringBuffer string;
+    args.at(exec, 0)->toString(exec).getCString(string);
+    puts(string.data());
+    return jsUndefined();
+}
+#endif
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
new file mode 100644
index 0000000..8df700d
--- /dev/null
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSGlobalObjectFunctions_h
+#define JSGlobalObjectFunctions_h
+
+#include "JSImmediate.h" // temporary until JSValue* becomes a class we can forward-declare
+
+namespace JSC {
+
+    class ArgList;
+    class ExecState;
+    class JSObject;
+
+    // FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
+    // is a 0.5% reduction.
+
+    JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
+    JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
+#ifndef NDEBUG
+    JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
+#endif
+
+    static const double mantissaOverflowLowerBound = 9007199254740992.0;
+    double parseIntOverflow(const char*, int length, int radix);
+
+} // namespace JSC
+
+#endif // JSGlobalObjectFunctions_h
diff --git a/JavaScriptCore/runtime/JSImmediate.cpp b/JavaScriptCore/runtime/JSImmediate.cpp
new file mode 100644
index 0000000..e70d66a
--- /dev/null
+++ b/JavaScriptCore/runtime/JSImmediate.cpp
@@ -0,0 +1,81 @@
+/*
+ *  Copyright (C) 2003-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.
+ *
+ */
+
+#include "config.h"
+#include "JSImmediate.h"
+
+#include "BooleanConstructor.h"
+#include "BooleanPrototype.h"
+#include "Error.h"
+#include "ExceptionHelpers.h"
+#include "JSGlobalObject.h"
+#include "JSNotAnObject.h"
+#include "NumberConstructor.h"
+#include "NumberPrototype.h"
+
+namespace JSC {
+
+JSObject* JSImmediate::toObject(JSValue* v, ExecState* exec)
+{
+    ASSERT(isImmediate(v));
+    if (isNumber(v))
+        return constructNumberFromImmediateNumber(exec, v);
+    if (isBoolean(v))
+        return constructBooleanFromImmediateBoolean(exec, v);
+    
+    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
+    exec->setException(exception);
+    return new (exec) JSNotAnObject(exec, exception);
+}
+
+JSObject* JSImmediate::prototype(JSValue* v, ExecState* exec)
+{
+    ASSERT(isImmediate(v));
+    if (isNumber(v))
+        return exec->lexicalGlobalObject()->numberPrototype();
+    if (isBoolean(v))
+        return exec->lexicalGlobalObject()->booleanPrototype();
+
+    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
+    exec->setException(exception);
+    return new (exec) JSNotAnObject(exec, exception);
+}
+
+UString JSImmediate::toString(JSValue* v)
+{
+    ASSERT(isImmediate(v));
+    if (isNumber(v))
+        return UString::from(getTruncatedInt32(v));
+    if (v == jsBoolean(false))
+        return "false";
+    if (v == jsBoolean(true))
+        return "true";
+    if (v->isNull())
+        return "null";
+    ASSERT(v == jsUndefined());
+    return "undefined";
+}
+
+NEVER_INLINE double JSImmediate::nonInlineNaN()
+{
+    return std::numeric_limits<double>::quiet_NaN();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h
new file mode 100644
index 0000000..5214df5
--- /dev/null
+++ b/JavaScriptCore/runtime/JSImmediate.h
@@ -0,0 +1,468 @@
+/*
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KJS_JS_IMMEDIATE_H
+#define KJS_JS_IMMEDIATE_H
+
+#include <wtf/Assertions.h>
+#include <wtf/AlwaysInline.h>
+#include <wtf/MathExtras.h>
+#include <limits>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+namespace JSC {
+
+    class ExecState;
+    class JSCell;
+    class JSObject;
+    class JSValue;
+    class UString;
+
+    inline JSValue* noValue() { return 0; }
+    inline void* asPointer(JSValue* value) { return value; }
+
+    /*
+     * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged 
+     * value masquerading as a pointer). The low two bits in a JSValue* are available for type tagging
+     * because allocator alignment guarantees they will be 00 in cell pointers.
+     *
+     * For example, on a 32 bit system:
+     *
+     * JSCell*:             XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                     00
+     *                      [ high 30 bits: pointer address ]  [ low 2 bits -- always 0 ]
+     * JSImmediate:         XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                     TT
+     *                      [ high 30 bits: 'payload' ]             [ low 2 bits -- tag ]
+     *
+     * Where the bottom two bits are non-zero they either indicate that the immediate is a 31 bit signed
+     * integer, or they mark the value as being an immediate of a type other than integer, with a secondary
+     * tag used to indicate the exact type.
+     *
+     * Where the lowest bit is set (TT is equal to 01 or 11) the high 31 bits form a 31 bit signed int value.
+     * Where TT is equal to 10 this indicates this is a type of immediate other than an integer, and the next
+     * two bits will form an extended tag.
+     *
+     * 31 bit signed int:   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                     X1
+     *                      [ high 30 bits of the value ]      [ high bit part of value ]
+     * Other:               YYYYYYYYYYYYYYYYYYYYYYYYYYYY      ZZ               10
+     *                      [ extended 'payload' ]  [  extended tag  ]  [  tag 'other'  ]
+     *
+     * Where the first bit of the extended tag is set this flags the value as being a boolean, and the following
+     * bit would flag the value as undefined.  If neither bits are set, the value is null.
+     *
+     * Other:               YYYYYYYYYYYYYYYYYYYYYYYYYYYY      UB               10
+     *                      [ extended 'payload' ]  [ undefined | bool ]  [ tag 'other' ]
+     *
+     * For boolean value the lowest bit in the payload holds the value of the bool, all remaining bits are zero.
+     * For undefined or null immediates the payload is zero.
+     *
+     * Boolean:             000000000000000000000000000V      01               10
+     *                      [ boolean value ]              [ bool ]       [ tag 'other' ]
+     * Undefined:           0000000000000000000000000000      10               10
+     *                      [ zero ]                    [ undefined ]     [ tag 'other' ]
+     * Null:                0000000000000000000000000000      00               10
+     *                      [ zero ]                       [ zero ]       [ tag 'other' ]
+     */
+
+    class JSImmediate {
+    private:
+        friend class CTI; // Whooo!
+    
+        static const uintptr_t TagMask           = 0x3u; // primary tag is 2 bits long
+        static const uintptr_t TagBitTypeInteger = 0x1u; // bottom bit set indicates integer, this dominates the following bit
+        static const uintptr_t TagBitTypeOther   = 0x2u; // second bit set indicates immediate other than an integer
+
+        static const uintptr_t ExtendedTagMask         = 0xCu; // extended tag holds a further two bits
+        static const uintptr_t ExtendedTagBitBool      = 0x4u;
+        static const uintptr_t ExtendedTagBitUndefined = 0x8u;
+
+        static const uintptr_t FullTagTypeMask      = TagMask | ExtendedTagMask;
+        static const uintptr_t FullTagTypeBool      = TagBitTypeOther | ExtendedTagBitBool;
+        static const uintptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
+        static const uintptr_t FullTagTypeNull      = TagBitTypeOther;
+
+        static const uint32_t IntegerPayloadShift  = 1u;
+        static const uint32_t ExtendedPayloadShift = 4u;
+
+        static const uintptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
+ 
+    public:
+        static ALWAYS_INLINE bool isImmediate(JSValue* v)
+        {
+            return rawValue(v) & TagMask;
+        }
+        
+        static ALWAYS_INLINE bool isNumber(JSValue* v)
+        {
+            return rawValue(v) & TagBitTypeInteger;
+        }
+
+        static ALWAYS_INLINE bool isPositiveNumber(JSValue* v)
+        {
+            // A single mask to check for the sign bit and the number tag all at once.
+            return (rawValue(v) & (0x80000000 | TagBitTypeInteger)) == TagBitTypeInteger;
+        }
+        
+        static ALWAYS_INLINE bool isBoolean(JSValue* v)
+        {
+            return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool;
+        }
+        
+        static ALWAYS_INLINE bool isUndefinedOrNull(JSValue* v)
+        {
+            // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
+            return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
+        }
+
+        static bool isNegative(JSValue* v)
+        {
+            ASSERT(isNumber(v));
+            return rawValue(v) & 0x80000000;
+        }
+
+        static JSValue* from(char);
+        static JSValue* from(signed char);
+        static JSValue* from(unsigned char);
+        static JSValue* from(short);
+        static JSValue* from(unsigned short);
+        static JSValue* from(int);
+        static JSValue* from(unsigned);
+        static JSValue* from(long);
+        static JSValue* from(unsigned long);
+        static JSValue* from(long long);
+        static JSValue* from(unsigned long long);
+        static JSValue* from(double);
+
+        static ALWAYS_INLINE bool isEitherImmediate(JSValue* v1, JSValue* v2)
+        {
+            return (rawValue(v1) | rawValue(v2)) & TagMask;
+        }
+
+        static ALWAYS_INLINE bool isAnyImmediate(JSValue* v1, JSValue* v2, JSValue* v3)
+        {
+            return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask;
+        }
+
+        static ALWAYS_INLINE bool areBothImmediate(JSValue* v1, JSValue* v2)
+        {
+            return isImmediate(v1) & isImmediate(v2);
+        }
+
+        static ALWAYS_INLINE bool areBothImmediateNumbers(JSValue* v1, JSValue* v2)
+        {
+            return rawValue(v1) & rawValue(v2) & TagBitTypeInteger;
+        }
+
+        static ALWAYS_INLINE JSValue* andImmediateNumbers(JSValue* v1, JSValue* v2)
+        {
+            ASSERT(areBothImmediateNumbers(v1, v2));
+            return makeValue(rawValue(v1) & rawValue(v2));
+        }
+
+        static ALWAYS_INLINE JSValue* xorImmediateNumbers(JSValue* v1, JSValue* v2)
+        {
+            ASSERT(areBothImmediateNumbers(v1, v2));
+            return makeValue((rawValue(v1) ^ rawValue(v2)) | TagBitTypeInteger);
+        }
+
+        static ALWAYS_INLINE JSValue* orImmediateNumbers(JSValue* v1, JSValue* v2)
+        {
+            ASSERT(areBothImmediateNumbers(v1, v2));
+            return makeValue(rawValue(v1) | rawValue(v2));
+        }
+
+        static ALWAYS_INLINE JSValue* rightShiftImmediateNumbers(JSValue* val, JSValue* shift)
+        {
+            ASSERT(areBothImmediateNumbers(val, shift));
+            return makeValue((static_cast<intptr_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagBitTypeInteger);
+        }
+
+        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue* v)
+        {
+            // Number is non-negative and an operation involving two of these can't overflow.
+            // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
+            return (rawValue(v) & (TagBitTypeInteger + (3u << 30))) == TagBitTypeInteger;
+        }
+
+        static ALWAYS_INLINE JSValue* addImmediateNumbers(JSValue* v1, JSValue* v2)
+        {
+            ASSERT(canDoFastAdditiveOperations(v1));
+            ASSERT(canDoFastAdditiveOperations(v2));
+            return makeValue(rawValue(v1) + rawValue(v2) - TagBitTypeInteger);
+        }
+
+        static ALWAYS_INLINE JSValue* subImmediateNumbers(JSValue* v1, JSValue* v2)
+        {
+            ASSERT(canDoFastAdditiveOperations(v1));
+            ASSERT(canDoFastAdditiveOperations(v2));
+            return makeValue(rawValue(v1) - rawValue(v2) + TagBitTypeInteger);
+        }
+
+        static ALWAYS_INLINE JSValue* incImmediateNumber(JSValue* v)
+        {
+            ASSERT(canDoFastAdditiveOperations(v));
+            return makeValue(rawValue(v) + (1 << IntegerPayloadShift));
+        }
+
+        static ALWAYS_INLINE JSValue* decImmediateNumber(JSValue* v)
+        {
+            ASSERT(canDoFastAdditiveOperations(v));
+            return makeValue(rawValue(v) - (1 << IntegerPayloadShift));
+        }
+
+        static double toDouble(JSValue*);
+        static bool toBoolean(JSValue*);
+        static JSObject* toObject(JSValue*, ExecState*);
+        static UString toString(JSValue*);
+
+        static bool getUInt32(JSValue*, uint32_t&);
+        static bool getTruncatedInt32(JSValue*, int32_t&);
+        static bool getTruncatedUInt32(JSValue*, uint32_t&);
+
+        static int32_t getTruncatedInt32(JSValue*);
+        static uint32_t getTruncatedUInt32(JSValue*);
+
+        static JSValue* trueImmediate();
+        static JSValue* falseImmediate();
+        static JSValue* undefinedImmediate();
+        static JSValue* nullImmediate();
+        static JSValue* zeroImmediate();
+        static JSValue* oneImmediate();
+
+        static JSValue* impossibleValue();
+        
+        static JSObject* prototype(JSValue*, ExecState*);
+
+    private:
+        static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
+        static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
+        static const unsigned maxImmediateUInt = maxImmediateInt;
+
+        static ALWAYS_INLINE JSValue* makeValue(uintptr_t integer)
+        {
+            return reinterpret_cast<JSValue*>(integer);
+        }
+
+        static ALWAYS_INLINE JSValue* makeInt(int32_t value)
+        {
+            return makeValue((value << IntegerPayloadShift) | TagBitTypeInteger);
+        }
+        
+        static ALWAYS_INLINE JSValue* makeBool(bool b)
+        {
+            return makeValue((static_cast<uintptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
+        }
+        
+        static ALWAYS_INLINE JSValue* makeUndefined()
+        {
+            return makeValue(FullTagTypeUndefined);
+        }
+        
+        static ALWAYS_INLINE JSValue* makeNull()
+        {
+            return makeValue(FullTagTypeNull);
+        }
+        
+        static ALWAYS_INLINE int32_t intValue(JSValue* v)
+        {
+            return static_cast<int32_t>(static_cast<intptr_t>(rawValue(v)) >> IntegerPayloadShift);
+        }
+        
+        static ALWAYS_INLINE uint32_t uintValue(JSValue* v)
+        {
+            return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift);
+        }
+        
+        static ALWAYS_INLINE bool boolValue(JSValue* v)
+        {
+            return rawValue(v) & ExtendedPayloadBitBoolValue;
+        }
+        
+        static ALWAYS_INLINE uintptr_t rawValue(JSValue* v)
+        {
+            return reinterpret_cast<uintptr_t>(v);
+        }
+
+        static double nonInlineNaN();
+    };
+
+    ALWAYS_INLINE JSValue* JSImmediate::trueImmediate() { return makeBool(true); }
+    ALWAYS_INLINE JSValue* JSImmediate::falseImmediate() { return makeBool(false); }
+    ALWAYS_INLINE JSValue* JSImmediate::undefinedImmediate() { return makeUndefined(); }
+    ALWAYS_INLINE JSValue* JSImmediate::nullImmediate() { return makeNull(); }
+    ALWAYS_INLINE JSValue* JSImmediate::zeroImmediate() { return makeInt(0); }
+    ALWAYS_INLINE JSValue* JSImmediate::oneImmediate() { return makeInt(1); }
+
+    // This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate
+    ALWAYS_INLINE JSValue* JSImmediate::impossibleValue() { return makeValue(0x4); }
+
+    ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue* v)
+    {
+        ASSERT(isImmediate(v));
+        uintptr_t bits = rawValue(v);
+        return (bits & TagBitTypeInteger)
+            ? bits != TagBitTypeInteger // !0 ints
+            : bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue); // bool true
+    }
+
+    ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue* v)
+    {
+        ASSERT(isNumber(v));
+        return intValue(v);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(char i)
+    {
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(signed char i)
+    {
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(unsigned char i)
+    {
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(short i)
+    {
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(unsigned short i)
+    {
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(int i)
+    {
+        if ((i < minImmediateInt) | (i > maxImmediateInt))
+            return noValue();
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(unsigned i)
+    {
+        if (i > maxImmediateUInt)
+            return noValue();
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(long i)
+    {
+        if ((i < minImmediateInt) | (i > maxImmediateInt))
+            return noValue();
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long i)
+    {
+        if (i > maxImmediateUInt)
+            return noValue();
+        return makeInt(i);
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(long long i)
+    {
+        if ((i < minImmediateInt) | (i > maxImmediateInt))
+            return noValue();
+        return makeInt(static_cast<uintptr_t>(i));
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long long i)
+    {
+        if (i > maxImmediateUInt)
+            return noValue();
+        return makeInt(static_cast<uintptr_t>(i));
+    }
+
+    ALWAYS_INLINE JSValue* JSImmediate::from(double d)
+    {
+        const int intVal = static_cast<int>(d);
+
+        if ((intVal < minImmediateInt) | (intVal > maxImmediateInt))
+            return noValue();
+
+        // Check for data loss from conversion to int.
+        if (intVal != d || (!intVal && signbit(d)))
+            return noValue();
+
+        return makeInt(intVal);
+    }
+
+    ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue* v)
+    {
+        ASSERT(isNumber(v));
+        return intValue(v);
+    }
+
+    ALWAYS_INLINE double JSImmediate::toDouble(JSValue* v)
+    {
+        ASSERT(isImmediate(v));
+        int i;
+        if (isNumber(v))
+            i = intValue(v);
+        else if (rawValue(v) == FullTagTypeUndefined)
+            return nonInlineNaN();
+        else
+            i = rawValue(v) >> ExtendedPayloadShift;
+        return i;
+    }
+
+    ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue* v, uint32_t& i)
+    {
+        i = uintValue(v);
+        return isPositiveNumber(v);
+    }
+
+    ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue* v, int32_t& i)
+    {
+        i = intValue(v);
+        return isNumber(v);
+    }
+
+    ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue* v, uint32_t& i)
+    {
+        return getUInt32(v, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsUndefined()
+    {
+        return JSImmediate::undefinedImmediate();
+    }
+
+    inline JSValue* jsNull()
+    {
+        return JSImmediate::nullImmediate();
+    }
+
+    inline JSValue* jsBoolean(bool b)
+    {
+        return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
+    }
+
+} // namespace JSC
+
+#endif
diff --git a/JavaScriptCore/runtime/JSLock.cpp b/JavaScriptCore/runtime/JSLock.cpp
new file mode 100644
index 0000000..ee7fb3b
--- /dev/null
+++ b/JavaScriptCore/runtime/JSLock.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2005, 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 NU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA 
+ *
+ */
+
+#include "config.h"
+#include "JSLock.h"
+
+#include "collector.h"
+#include "ExecState.h"
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+#include <pthread.h>
+#endif
+
+namespace JSC {
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+// Acquire this mutex before accessing lock-related data.
+static pthread_mutex_t JSMutex = PTHREAD_MUTEX_INITIALIZER;
+
+// Thread-specific key that tells whether a thread holds the JSMutex, and how many times it was taken recursively.
+pthread_key_t JSLockCount;
+
+static void createJSLockCount()
+{
+    pthread_key_create(&JSLockCount, 0);
+}
+
+pthread_once_t createJSLockCountOnce = PTHREAD_ONCE_INIT;
+
+// Lock nesting count.
+intptr_t JSLock::lockCount()
+{
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+    return reinterpret_cast<intptr_t>(pthread_getspecific(JSLockCount));
+}
+
+static void setLockCount(intptr_t count)
+{
+    ASSERT(count >= 0);
+    pthread_setspecific(JSLockCount, reinterpret_cast<void*>(count));
+}
+
+JSLock::JSLock(ExecState* exec)
+    : m_lockingForReal(exec->globalData().isSharedInstance)
+{
+    lock(m_lockingForReal);
+}
+
+void JSLock::lock(bool lockForReal)
+{
+#ifdef NDEBUG
+    // Locking "not for real" is a debug-only feature.
+    if (!lockForReal)
+        return;
+#endif
+
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+    intptr_t currentLockCount = lockCount();
+    if (!currentLockCount && lockForReal) {
+        int result;
+        result = pthread_mutex_lock(&JSMutex);
+        ASSERT(!result);
+    }
+    setLockCount(currentLockCount + 1);
+}
+
+void JSLock::unlock(bool lockForReal)
+{
+    ASSERT(lockCount());
+
+#ifdef NDEBUG
+    // Locking "not for real" is a debug-only feature.
+    if (!lockForReal)
+        return;
+#endif
+
+    intptr_t newLockCount = lockCount() - 1;
+    setLockCount(newLockCount);
+    if (!newLockCount && lockForReal) {
+        int result;
+        result = pthread_mutex_unlock(&JSMutex);
+        ASSERT(!result);
+    }
+}
+
+void JSLock::lock(ExecState* exec)
+{
+    lock(exec->globalData().isSharedInstance);
+}
+
+void JSLock::unlock(ExecState* exec)
+{
+    unlock(exec->globalData().isSharedInstance);
+}
+
+bool JSLock::currentThreadIsHoldingLock()
+{
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+    return !!pthread_getspecific(JSLockCount);
+}
+
+JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
+    : m_lockingForReal(exec->globalData().isSharedInstance)
+{
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+    m_lockCount = JSLock::lockCount();
+    for (intptr_t i = 0; i < m_lockCount; i++)
+        JSLock::unlock(m_lockingForReal);
+}
+
+JSLock::DropAllLocks::DropAllLocks(bool lockingForReal)
+    : m_lockingForReal(lockingForReal)
+{
+    pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+    // It is necessary to drop even "unreal" locks, because having a non-zero lock count
+    // will prevent a real lock from being taken.
+
+    m_lockCount = JSLock::lockCount();
+    for (intptr_t i = 0; i < m_lockCount; i++)
+        JSLock::unlock(m_lockingForReal);
+}
+
+JSLock::DropAllLocks::~DropAllLocks()
+{
+    for (intptr_t i = 0; i < m_lockCount; i++)
+        JSLock::lock(m_lockingForReal);
+}
+
+#else
+
+JSLock::JSLock(ExecState*)
+    : m_lockingForReal(false)
+{
+}
+
+// If threading support is off, set the lock count to a constant value of 1 so ssertions
+// that the lock is held don't fail
+intptr_t JSLock::lockCount()
+{
+    return 1;
+}
+
+bool JSLock::currentThreadIsHoldingLock()
+{
+    return true;
+}
+
+void JSLock::lock(bool)
+{
+}
+
+void JSLock::unlock(bool)
+{
+}
+
+void JSLock::lock(ExecState*)
+{
+}
+
+void JSLock::unlock(ExecState*)
+{
+}
+
+JSLock::DropAllLocks::DropAllLocks(ExecState*)
+{
+}
+
+JSLock::DropAllLocks::DropAllLocks(bool)
+{
+}
+
+JSLock::DropAllLocks::~DropAllLocks()
+{
+}
+
+#endif // USE(MULTIPLE_THREADS)
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSLock.h b/JavaScriptCore/runtime/JSLock.h
new file mode 100644
index 0000000..0c22ff8
--- /dev/null
+++ b/JavaScriptCore/runtime/JSLock.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KJS_JSLock_h
+#define KJS_JSLock_h
+
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+    // To make it safe to use JavaScript on multiple threads, it is
+    // important to lock before doing anything that allocates a
+    // JavaScript data structure or that interacts with shared state
+    // such as the protect count hash table. The simplest way to lock
+    // is to create a local JSLock object in the scope where the lock 
+    // must be held. The lock is recursive so nesting is ok. The JSLock 
+    // object also acts as a convenience short-hand for running important
+    // initialization routines.
+
+    // To avoid deadlock, sometimes it is necessary to temporarily
+    // release the lock. Since it is recursive you actually have to
+    // release all locks held by your thread. This is safe to do if
+    // you are executing code that doesn't require the lock, and you
+    // reacquire the right number of locks at the end. You can do this
+    // by constructing a locally scoped JSLock::DropAllLocks object. The 
+    // DropAllLocks object takes care to release the JSLock only if your
+    // thread acquired it to begin with.
+
+    // For contexts other than the single shared one, implicit locking is not done,
+    // but we still need to perform all the counting in order to keep debug
+    // assertions working, so that clients that use the shared context don't break.
+
+    class ExecState;
+
+    class JSLock : Noncopyable {
+    public:
+        JSLock(ExecState*);
+
+        JSLock(bool lockingForReal)
+            : m_lockingForReal(lockingForReal)
+        {
+#ifdef NDEBUG
+            // Locking "not for real" is a debug-only feature.
+            if (!lockingForReal)
+                return;
+#endif
+            lock(lockingForReal);
+        }
+
+        ~JSLock()
+        { 
+#ifdef NDEBUG
+            // Locking "not for real" is a debug-only feature.
+            if (!m_lockingForReal)
+                return;
+#endif
+            unlock(m_lockingForReal); 
+        }
+        
+        static void lock(bool);
+        static void unlock(bool);
+        static void lock(ExecState*);
+        static void unlock(ExecState*);
+
+        static intptr_t lockCount();
+        static bool currentThreadIsHoldingLock();
+
+        bool m_lockingForReal;
+
+        class DropAllLocks : Noncopyable {
+        public:
+            DropAllLocks(ExecState* exec);
+            DropAllLocks(bool);
+            ~DropAllLocks();
+            
+        private:
+            intptr_t m_lockCount;
+            bool m_lockingForReal;
+        };
+    };
+
+} // namespace
+
+#endif // KJS_JSLock_h
diff --git a/JavaScriptCore/runtime/JSNotAnObject.cpp b/JavaScriptCore/runtime/JSNotAnObject.cpp
new file mode 100644
index 0000000..c4ca8fd
--- /dev/null
+++ b/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "JSNotAnObject.h"
+
+#include <wtf/UnusedParam.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
+
+// JSValue methods
+JSValue* JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return m_exception;
+}
+
+bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue*&)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return false;
+}
+
+bool JSNotAnObject::toBoolean(ExecState* exec) const
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return false;
+}
+
+double JSNotAnObject::toNumber(ExecState* exec) const
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return NaN;
+}
+
+UString JSNotAnObject::toString(ExecState* exec) const
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return "";
+}
+
+JSObject* JSNotAnObject::toObject(ExecState* exec) const
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return m_exception;
+}
+
+// Marking
+void JSNotAnObject::mark()
+{
+    JSCell::mark();
+    if (!m_exception->marked())
+        m_exception->mark();
+}
+
+// JSObject methods
+bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, const Identifier&, PropertySlot&)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return false;
+}
+
+bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return false;
+}
+
+void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*, PutPropertySlot&)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+}
+
+void JSNotAnObject::put(ExecState* exec, unsigned, JSValue*)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+}
+
+bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier&)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return false;
+}
+
+bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+    return false;
+}
+
+void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&)
+{
+    UNUSED_PARAM(exec);
+    ASSERT(exec->hadException() && exec->exception() == m_exception);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSNotAnObject.h b/JavaScriptCore/runtime/JSNotAnObject.h
new file mode 100644
index 0000000..b6e2931
--- /dev/null
+++ b/JavaScriptCore/runtime/JSNotAnObject.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 JSNotAnObject_h
+#define JSNotAnObject_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class JSNotAnObjectErrorStub : public JSObject {
+    public:
+        JSNotAnObjectErrorStub(ExecState* exec, bool isNull)
+            : JSObject(exec->globalData().notAnObjectErrorStubStructure)
+            , m_isNull(isNull)
+        {
+        }
+
+        bool isNull() const { return m_isNull; }
+
+    private:
+        virtual bool isNotAnObjectErrorStub() const { return true; }
+
+        bool m_isNull;
+    };
+    
+    // This unholy class is used to allow us to avoid multiple exception checks
+    // in certain SquirrelFish opcodes -- effectively it just silently consumes
+    // any operations performed on the result of a failed toObject call.
+    class JSNotAnObject : public JSObject {
+    public:
+        JSNotAnObject(ExecState* exec, JSNotAnObjectErrorStub* exception)
+            : JSObject(exec->globalData().notAnObjectStructure)
+            , m_exception(exception)
+        {
+        }
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+
+     private:
+        // JSValue methods
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+
+        // Marking
+        virtual void mark();
+
+        // JSObject methods
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue*);
+
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+        virtual bool deleteProperty(ExecState*, unsigned propertyName);
+
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+
+        JSNotAnObjectErrorStub* m_exception;
+    };
+
+} // namespace JSC
+
+#endif // JSNotAnObject_h
diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp
new file mode 100644
index 0000000..5b3f3bd
--- /dev/null
+++ b/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -0,0 +1,124 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSNumberCell.h"
+
+#include "NumberObject.h"
+#include "ustring.h"
+
+namespace JSC {
+
+JSValue* JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+    return const_cast<JSNumberCell*>(this);
+}
+
+bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
+{
+    number = m_value;
+    value = this;
+    return true;
+}
+
+bool JSNumberCell::toBoolean(ExecState*) const
+{
+    return m_value < 0.0 || m_value > 0.0; // false for NaN
+}
+
+double JSNumberCell::toNumber(ExecState*) const
+{
+  return m_value;
+}
+
+UString JSNumberCell::toString(ExecState*) const
+{
+    if (m_value == 0.0) // +0.0 or -0.0
+        return "0";
+    return UString::from(m_value);
+}
+
+UString JSNumberCell::toThisString(ExecState*) const
+{
+    if (m_value == 0.0) // +0.0 or -0.0
+        return "0";
+    return UString::from(m_value);
+}
+
+JSObject* JSNumberCell::toObject(ExecState* exec) const
+{
+    return constructNumber(exec, const_cast<JSNumberCell*>(this));
+}
+
+JSObject* JSNumberCell::toThisObject(ExecState* exec) const
+{
+    return constructNumber(exec, const_cast<JSNumberCell*>(this));
+}
+
+bool JSNumberCell::getUInt32(uint32_t& uint32) const
+{
+    uint32 = static_cast<uint32_t>(m_value);
+    return uint32 == m_value;
+}
+
+bool JSNumberCell::getTruncatedInt32(int32_t& int32) const
+{
+    if (!(m_value >= -2147483648.0 && m_value < 2147483648.0))
+        return false;
+    int32 = static_cast<int32_t>(m_value);
+    return true;
+}
+
+bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const
+{
+    if (!(m_value >= 0.0 && m_value < 4294967296.0))
+        return false;
+    uint32 = static_cast<uint32_t>(m_value);
+    return true;
+}
+
+JSValue* JSNumberCell::getJSNumber()
+{
+    return this;
+}
+
+NEVER_INLINE JSValue* jsNumberCell(ExecState* exec, double d)
+{
+    return new (exec) JSNumberCell(exec, d);
+}
+
+NEVER_INLINE JSValue* jsNaN(ExecState* exec)
+{
+    return new (exec) JSNumberCell(exec, NaN);
+}
+
+NEVER_INLINE JSValue* jsNumberCell(JSGlobalData* globalData, double d)
+{
+    return new (globalData) JSNumberCell(globalData, d);
+}
+
+NEVER_INLINE JSValue* jsNaN(JSGlobalData* globalData)
+{
+    return new (globalData) JSNumberCell(globalData, NaN);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
new file mode 100644
index 0000000..e2f6990
--- /dev/null
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -0,0 +1,267 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSNumberCell_h
+#define JSNumberCell_h
+
+#include "ExecState.h"
+#include "JSCell.h"
+#include "JSImmediate.h"
+#include "collector.h"
+#include "ustring.h"
+#include <stddef.h> // for size_t
+
+namespace JSC {
+
+    class Identifier;
+    class JSCell;
+    class JSObject;
+    class JSString;
+    class PropertySlot;
+
+    struct ClassInfo;
+    struct Instruction;
+
+    class JSNumberCell : public JSCell {
+        friend class CTI;
+        friend JSValue* jsNumberCell(JSGlobalData*, double);
+        friend JSValue* jsNaN(JSGlobalData*);
+        friend JSValue* jsNumberCell(ExecState*, double);
+        friend JSValue* jsNaN(ExecState*);
+    public:
+        double value() const { return m_value; }
+
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+
+        virtual UString toThisString(ExecState*) const;
+        virtual JSObject* toThisObject(ExecState*) const;
+        virtual JSValue* getJSNumber();
+
+        int32_t toInt32() const;
+        uint32_t toUInt32() const;
+
+        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<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
+
+        JSNumberCell(JSGlobalData* globalData)
+        : JSCell(globalData->numberStructureID.get())
+        {
+        }
+
+    private:
+        JSNumberCell(JSGlobalData* globalData, double value)
+            : JSCell(globalData->numberStructureID.get())
+            , m_value(value)
+        {
+        }
+
+        JSNumberCell(ExecState* exec, double value)
+            : JSCell(exec->globalData().numberStructureID.get())
+            , m_value(value)
+        {
+        }
+
+        virtual bool getUInt32(uint32_t&) const;
+        virtual bool getTruncatedInt32(int32_t&) const;
+        virtual bool getTruncatedUInt32(uint32_t&) const;
+
+        double m_value;
+    };
+
+    extern const double NaN;
+    extern const double Inf;
+
+    JSNumberCell* asNumberCell(JSValue*);
+
+    JSValue* jsNumberCell(JSGlobalData*, double);
+    JSValue* jsNaN(JSGlobalData*);
+    JSValue* jsNumberCell(ExecState*, double);
+    JSValue* jsNaN(ExecState*);
+
+    inline JSNumberCell* asNumberCell(JSValue* value)
+    {
+        ASSERT(asCell(value)->isNumber());
+        return static_cast<JSNumberCell*>(asCell(value));
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
+    {
+        JSValue* v = JSImmediate::from(d);
+        return v ? v : jsNumberCell(exec, d);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, short i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned short i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, static_cast<double>(i));
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(exec, static_cast<double>(i));
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, double d)
+    {
+        JSValue* v = JSImmediate::from(d);
+        return v ? v : jsNumberCell(globalData, d);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, short i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned short i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, int i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+    }
+
+    ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long long i)
+    {
+        JSValue* v = JSImmediate::from(i);
+        return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+    }
+
+    // --- JSValue inlines ----------------------------
+
+    inline double JSValue::uncheckedGetNumber() const
+    {
+        ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
+    }
+
+    inline int32_t JSNumberCell::toInt32() const
+    {
+        if (m_value >= -2147483648.0 && m_value < 2147483648.0)
+            return static_cast<int32_t>(m_value);
+        bool scratch;
+        return JSC::toInt32SlowCase(m_value, scratch);
+    }
+
+    inline uint32_t JSNumberCell::toUInt32() const
+    {
+        if (m_value >= 0.0 && m_value < 4294967296.0)
+            return static_cast<uint32_t>(m_value);
+        bool scratch;
+        return JSC::toUInt32SlowCase(m_value, scratch);
+    }
+
+    ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
+    {
+        return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
+    }
+
+} // namespace JSC
+
+#endif // JSNumberCell_h
diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp
new file mode 100644
index 0000000..82c1c63
--- /dev/null
+++ b/JavaScriptCore/runtime/JSObject.cpp
@@ -0,0 +1,516 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSObject.h"
+
+#include "DatePrototype.h"
+#include "ErrorConstructor.h"
+#include "GetterSetter.h"
+#include "JSGlobalObject.h"
+#include "NativeErrorConstructor.h"
+#include "ObjectPrototype.h"
+#include "PropertyNameArray.h"
+#include "lookup.h"
+#include "nodes.h"
+#include "operations.h"
+#include <math.h>
+#include <wtf/Assertions.h>
+
+#define JSOBJECT_MARK_TRACING 0
+
+#if JSOBJECT_MARK_TRACING
+
+#define JSOBJECT_MARK_BEGIN() \
+    static int markStackDepth = 0; \
+    for (int i = 0; i < markStackDepth; i++) \
+        putchar('-'); \
+    printf("%s (%p)\n", className().UTF8String().c_str(), this); \
+    markStackDepth++; \
+
+#define JSOBJECT_MARK_END() \
+    markStackDepth--;
+
+#else // JSOBJECT_MARK_TRACING
+
+#define JSOBJECT_MARK_BEGIN()
+#define JSOBJECT_MARK_END()
+
+#endif // JSOBJECT_MARK_TRACING
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSObject);
+
+void JSObject::mark()
+{
+    JSOBJECT_MARK_BEGIN();
+
+    JSCell::mark();
+    m_structureID->mark();
+
+    size_t storageSize = m_structureID->propertyStorageSize();
+    for (size_t i = 0; i < storageSize; ++i) {
+        JSValue* v = m_propertyStorage[i];
+        if (!v->marked())
+            v->mark();
+    }
+
+    JSOBJECT_MARK_END();
+}
+
+UString JSObject::className() const
+{
+    const ClassInfo* info = classInfo();
+    if (info)
+        return info->className;
+    return "Object";
+}
+
+bool JSObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
+}
+
+static void throwSetterError(ExecState* exec)
+{
+    throwError(exec, TypeError, "setting a property that has only a getter");
+}
+
+// ECMA 8.6.2.2
+void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    ASSERT(value);
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        JSObject* proto = value->getObject();
+
+        // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
+        if (!proto && !value->isNull())
+            return;
+        
+        while (proto) {
+            if (proto == this) {
+                throwError(exec, GeneralError, "cyclic __proto__ value");
+                return;
+            }
+            proto = proto->prototype() ? proto->prototype()->getObject() : 0;
+        }
+        
+        setPrototype(value);
+        return;
+    }
+    
+    // Check if there are any setters or getters in the prototype chain
+    JSValue* prototype;
+    for (JSObject* obj = this; !obj->structureID()->hasGetterSetterProperties(); obj = asObject(prototype)) {
+        prototype = obj->prototype();
+        if (prototype->isNull()) {
+            putDirect(propertyName, value, 0, true, slot);
+            return;
+        }
+    }
+    
+    unsigned attributes;
+    if ((m_structureID->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
+        return;
+
+    for (JSObject* obj = this; ; obj = asObject(prototype)) {
+        if (JSValue* gs = obj->getDirect(propertyName)) {
+            if (gs->isGetterSetter()) {
+                JSObject* setterFunc = asGetterSetter(gs)->setter();        
+                if (!setterFunc) {
+                    throwSetterError(exec);
+                    return;
+                }
+                
+                CallData callData;
+                CallType callType = setterFunc->getCallData(callData);
+                ArgList args;
+                args.append(value);
+                call(exec, setterFunc, callType, callData, this, args);
+                return;
+            }
+
+            // If there's an existing property on the object or one of its 
+            // prototypes it should be replaced, so break here.
+            break;
+        }
+
+        prototype = obj->prototype();
+        if (prototype->isNull())
+            break;
+    }
+
+    putDirect(propertyName, value, 0, true, slot);
+    return;
+}
+
+void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value)
+{
+    PutPropertySlot slot;
+    put(exec, Identifier::from(exec, propertyName), value, slot);
+}
+
+void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    putDirect(propertyName, value, attributes);
+}
+
+void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue* value, unsigned attributes)
+{
+    putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes);
+}
+
+bool JSObject::hasProperty(ExecState* exec, const Identifier& propertyName) const
+{
+    PropertySlot slot;
+    return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot);
+}
+
+bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const
+{
+    PropertySlot slot;
+    return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot);
+}
+
+// ECMA 8.6.2.5
+bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    unsigned attributes;
+    if (m_structureID->get(propertyName, attributes) != WTF::notFound) {
+        if ((attributes & DontDelete))
+            return false;
+        removeDirect(propertyName);
+        return true;
+    }
+
+    // Look in the static hashtable of properties
+    const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
+    if (entry && entry->attributes() & DontDelete)
+        return false; // this builtin property can't be deleted
+
+    // FIXME: Should the code here actually do some deletion?
+    return true;
+}
+
+bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const
+{
+    PropertySlot slot;
+    return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot);
+}
+
+bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName)
+{
+    return deleteProperty(exec, Identifier::from(exec, propertyName));
+}
+
+static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
+{
+    JSValue* function = object->get(exec, propertyName);
+    CallData callData;
+    CallType callType = function->getCallData(callData);
+    if (callType == CallTypeNone)
+        return exec->exception();
+
+    // Prevent "toString" and "valueOf" from observing execution if an exception
+    // is pending.
+    if (exec->hadException())
+        return exec->exception();
+
+    JSValue* result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
+    ASSERT(!result->isGetterSetter());
+    if (exec->hadException())
+        return exec->exception();
+    if (result->isObject())
+        return noValue();
+    return result;
+}
+
+bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
+{
+    result = defaultValue(exec, PreferNumber);
+    number = result->toNumber(exec);
+    return !result->isString();
+}
+
+// ECMA 8.6.2.6
+JSValue* JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
+{
+    // Must call toString first for Date objects.
+    if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) {
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
+            return value;
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
+            return value;
+    } else {
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
+            return value;
+        if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
+            return value;
+    }
+
+    ASSERT(!exec->hadException());
+
+    return throwError(exec, TypeError, "No default value");
+}
+
+const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifier& propertyName) const
+{
+    for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
+        if (const HashTable* propHashTable = info->propHashTable(exec)) {
+            if (const HashEntry* entry = propHashTable->entry(exec, propertyName))
+                return entry;
+        }
+    }
+    return 0;
+}
+
+void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
+{
+    JSValue* object = getDirect(propertyName);
+    if (object && object->isGetterSetter()) {
+        ASSERT(m_structureID->hasGetterSetterProperties());
+        asGetterSetter(object)->setGetter(getterFunction);
+        return;
+    }
+
+    PutPropertySlot slot;
+    GetterSetter* getterSetter = new (exec) GetterSetter;
+    putDirect(propertyName, getterSetter, None, true, slot);
+
+    // putDirect will change our StructureID if we add a new property. For
+    // getters and setters, though, we also need to change our StructureID
+    // if we override an existing non-getter or non-setter.
+    if (slot.type() != PutPropertySlot::NewProperty) {
+        if (!m_structureID->isDictionary()) {
+            RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
+            setStructureID(structureID.release());
+        }
+    }
+
+    m_structureID->setHasGetterSetterProperties(true);
+    getterSetter->setGetter(getterFunction);
+}
+
+void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
+{
+    JSValue* object = getDirect(propertyName);
+    if (object && object->isGetterSetter()) {
+        ASSERT(m_structureID->hasGetterSetterProperties());
+        asGetterSetter(object)->setSetter(setterFunction);
+        return;
+    }
+
+    PutPropertySlot slot;
+    GetterSetter* getterSetter = new (exec) GetterSetter;
+    putDirect(propertyName, getterSetter, None, true, slot);
+
+    // putDirect will change our StructureID if we add a new property. For
+    // getters and setters, though, we also need to change our StructureID
+    // if we override an existing non-getter or non-setter.
+    if (slot.type() != PutPropertySlot::NewProperty) {
+        if (!m_structureID->isDictionary()) {
+            RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
+            setStructureID(structureID.release());
+        }
+    }
+
+    m_structureID->setHasGetterSetterProperties(true);
+    getterSetter->setSetter(setterFunction);
+}
+
+JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
+{
+    JSObject* object = this;
+    while (true) {
+        JSValue* value = object->getDirect(propertyName);
+        if (value) {
+            if (!value->isGetterSetter())
+                return jsUndefined();
+            JSObject* functionObject = asGetterSetter(value)->getter();
+            if (!functionObject)
+                return jsUndefined();
+            return functionObject;
+        }
+
+        if (!object->prototype() || !object->prototype()->isObject())
+            return jsUndefined();
+        object = asObject(object->prototype());
+    }
+}
+
+JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
+{
+    JSObject* object = this;
+    while (true) {
+        JSValue* value = object->getDirect(propertyName);
+        if (value) {
+            if (!value->isGetterSetter())
+                return jsUndefined();
+            JSObject* functionObject = asGetterSetter(value)->setter();
+            if (!functionObject)
+                return jsUndefined();
+            return functionObject;
+        }
+
+        if (!object->prototype() || !object->prototype()->isObject())
+            return jsUndefined();
+        object = asObject(object->prototype());
+    }
+}
+
+bool JSObject::hasInstance(ExecState* exec, JSValue* value, JSValue* proto)
+{
+    if (!proto->isObject()) {
+        throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
+        return false;
+    }
+
+    if (!value->isObject())
+        return false;
+
+    JSObject* object = asObject(value);
+    while ((object = object->prototype()->getObject())) {
+        if (object == proto)
+            return true;
+    }
+    return false;
+}
+
+bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyName) const
+{
+    unsigned attributes;
+    if (!getPropertyAttributes(exec, propertyName, attributes))
+        return false;
+    return !(attributes & DontEnum);
+}
+
+bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+{
+    if (m_structureID->get(propertyName, attributes) != WTF::notFound)
+        return true;
+    
+    // Look in the static hashtable of properties
+    const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
+    if (entry) {
+        attributes = entry->attributes();
+        return true;
+    }
+    
+    return false;
+}
+
+void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+{
+    m_structureID->getEnumerablePropertyNames(exec, propertyNames, this);
+}
+
+bool JSObject::toBoolean(ExecState*) const
+{
+    return true;
+}
+
+double JSObject::toNumber(ExecState* exec) const
+{
+    JSValue* primitive = toPrimitive(exec, PreferNumber);
+    if (exec->hadException()) // should be picked up soon in nodes.cpp
+        return 0.0;
+    return primitive->toNumber(exec);
+}
+
+UString JSObject::toString(ExecState* exec) const
+{
+    JSValue* primitive = toPrimitive(exec, PreferString);
+    if (exec->hadException())
+        return "";
+    return primitive->toString(exec);
+}
+
+JSObject* JSObject::toObject(ExecState*) const
+{
+    return const_cast<JSObject*>(this);
+}
+
+JSObject* JSObject::toThisObject(ExecState*) const
+{
+    return const_cast<JSObject*>(this);
+}
+
+JSGlobalObject* JSObject::toGlobalObject(ExecState*) const
+{
+    return 0;
+}
+
+void JSObject::removeDirect(const Identifier& propertyName)
+{
+    size_t offset;
+    if (m_structureID->isDictionary()) {
+        offset = m_structureID->removePropertyWithoutTransition(propertyName);
+        if (offset != WTF::notFound)
+            m_propertyStorage[offset] = jsUndefined();
+        return;
+    }
+
+    RefPtr<StructureID> structureID = StructureID::removePropertyTransition(m_structureID, propertyName, offset);
+    if (offset != WTF::notFound)
+        m_propertyStorage[offset] = jsUndefined();
+    setStructureID(structureID.release());
+}
+
+void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
+{
+    putDirect(Identifier(exec, function->name(&exec->globalData())), function, attr);
+}
+
+void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
+{
+    putDirectWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
+}
+
+NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue** location)
+{
+    if (JSObject* getterFunction = asGetterSetter(*location)->getter())
+        slot.setGetterSlot(getterFunction);
+    else
+        slot.setUndefined();
+}
+
+StructureID* JSObject::createInheritorID()
+{
+    m_inheritorID = JSObject::createStructureID(this);
+    return m_inheritorID.get();
+}
+
+void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
+{
+    allocatePropertyStorageInline(oldSize, newSize);
+}
+
+JSObject* constructEmptyObject(ExecState* exec)
+{
+    return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h
new file mode 100644
index 0000000..d280b64
--- /dev/null
+++ b/JavaScriptCore/runtime/JSObject.h
@@ -0,0 +1,541 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSObject_h
+#define JSObject_h
+
+#include "ArgList.h"
+#include "ClassInfo.h"
+#include "CommonIdentifiers.h"
+#include "ExecState.h"
+#include "JSNumberCell.h"
+#include "PropertySlot.h"
+#include "PutPropertySlot.h"
+#include "ScopeChain.h"
+#include "StructureID.h"
+
+namespace JSC {
+
+    class InternalFunction;
+    class PropertyNameArray;
+    class StructureID;
+    struct HashEntry;
+    struct HashTable;
+
+    // ECMA 262-3 8.6.1
+    // Property attributes
+    enum Attribute {
+        None         = 0,
+        ReadOnly     = 1 << 1,  // property can be only read, not written
+        DontEnum     = 1 << 2,  // property doesn't appear in (for .. in ..)
+        DontDelete   = 1 << 3,  // property can't be deleted
+        Function     = 1 << 4,  // property is a function - only used by static hashtables
+    };
+
+    typedef JSValue** PropertyStorage;
+
+    class JSObject : public JSCell {
+        friend class BatchedTransitionOptimizer;
+        friend class CTI;
+        friend class JSCell;
+
+    public:
+        explicit JSObject(PassRefPtr<StructureID>);
+
+        virtual void mark();
+
+        // The inline virtual destructor cannot be the first virtual function declared
+        // in the class as it results in the vtable being generated as a weak symbol
+        virtual ~JSObject();
+
+        bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
+
+        JSValue* prototype() const;
+        void setPrototype(JSValue* prototype);
+        
+        void setStructureID(PassRefPtr<StructureID>);
+        StructureID* inheritorID();
+
+        PropertyStorage& propertyStorage() { return m_propertyStorage; }
+
+        virtual UString className() const;
+
+        JSValue* get(ExecState*, const Identifier& propertyName) const;
+        JSValue* get(ExecState*, unsigned propertyName) const;
+
+        bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue* value);
+
+        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
+        virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValue* value, unsigned attributes);
+
+        bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
+
+        bool hasProperty(ExecState*, const Identifier& propertyName) const;
+        bool hasProperty(ExecState*, unsigned propertyName) const;
+        bool hasOwnProperty(ExecState*, const Identifier& propertyName) const;
+
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+        virtual bool deleteProperty(ExecState*, unsigned propertyName);
+
+        virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
+
+        virtual bool hasInstance(ExecState*, JSValue*, JSValue* prototypeProperty);
+
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+
+        virtual JSObject* toThisObject(ExecState*) const;
+        virtual JSGlobalObject* toGlobalObject(ExecState*) const;
+
+        virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+
+        // This get function only looks at the property map.
+        JSValue* getDirect(const Identifier& propertyName) const
+        {
+            size_t offset = m_structureID->get(propertyName);
+            return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
+        }
+
+        JSValue** getDirectLocation(const Identifier& propertyName)
+        {
+            size_t offset = m_structureID->get(propertyName);
+            return offset != WTF::notFound ? locationForOffset(offset) : 0;
+        }
+
+        JSValue** getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+        {
+            size_t offset = m_structureID->get(propertyName, attributes);
+            return offset != WTF::notFound ? locationForOffset(offset) : 0;
+        }
+
+        size_t offsetForLocation(JSValue** location)
+        {
+            return location - m_propertyStorage;
+        }
+
+        JSValue** locationForOffset(size_t offset)
+        {
+            return &m_propertyStorage[offset];
+        }
+
+        void transitionTo(StructureID*);
+
+        void removeDirect(const Identifier& propertyName);
+        bool hasCustomProperties() { return !m_structureID->isEmpty(); }
+        bool hasGetterSetterProperties() { return m_structureID->hasGetterSetterProperties(); }
+
+        void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
+        void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+        void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
+        void putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
+        void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
+
+        // Fast access to known property offsets.
+        JSValue* getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
+        void putDirectOffset(size_t offset, JSValue* value) { m_propertyStorage[offset] = value; }
+
+        void fillGetterPropertySlot(PropertySlot&, JSValue** location);
+
+        virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
+        virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
+        virtual JSValue* lookupGetter(ExecState*, const Identifier& propertyName);
+        virtual JSValue* lookupSetter(ExecState*, const Identifier& propertyName);
+
+        virtual bool isGlobalObject() const { return false; }
+        virtual bool isVariableObject() const { return false; }
+        virtual bool isWatchdogException() const { return false; }
+        virtual bool isNotAnObjectErrorStub() const { return false; }
+
+        void allocatePropertyStorage(size_t oldSize, size_t newSize);
+        void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
+        bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
+
+        static const size_t inlineStorageCapacity = 2;
+        static const size_t nonInlineBaseStorageCapacity = 16;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+        }
+
+    protected:
+        bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
+
+    private:
+        bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+
+        const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
+        StructureID* createInheritorID();
+
+        RefPtr<StructureID> m_inheritorID;
+
+        PropertyStorage m_propertyStorage;        
+        JSValue* m_inlineStorage[inlineStorageCapacity];
+    };
+
+    JSObject* asObject(JSValue*);
+
+    JSObject* constructEmptyObject(ExecState*);
+
+inline JSObject* asObject(JSValue* value)
+{
+    ASSERT(asCell(value)->isObject());
+    return static_cast<JSObject*>(asCell(value));
+}
+
+inline JSObject::JSObject(PassRefPtr<StructureID> structureID)
+    : JSCell(structureID.releaseRef()) // ~JSObject balances this ref()
+    , m_propertyStorage(m_inlineStorage)
+{
+    ASSERT(m_structureID);
+    ASSERT(m_structureID->propertyStorageCapacity() == inlineStorageCapacity);
+    ASSERT(m_structureID->isEmpty());
+    ASSERT(prototype()->isNull() || Heap::heap(this) == Heap::heap(prototype()));
+}
+
+inline JSObject::~JSObject()
+{
+    ASSERT(m_structureID);
+    if (m_propertyStorage != m_inlineStorage)
+        delete [] m_propertyStorage;
+    m_structureID->deref();
+}
+
+inline JSValue* JSObject::prototype() const
+{
+    return m_structureID->storedPrototype();
+}
+
+inline void JSObject::setPrototype(JSValue* prototype)
+{
+    ASSERT(prototype);
+    RefPtr<StructureID> newStructureID = StructureID::changePrototypeTransition(m_structureID, prototype);
+    setStructureID(newStructureID.release());
+}
+
+inline void JSObject::setStructureID(PassRefPtr<StructureID> structureID)
+{
+    m_structureID->deref();
+    m_structureID = structureID.releaseRef(); // ~JSObject balances this ref()
+}
+
+inline StructureID* JSObject::inheritorID()
+{
+    if (m_inheritorID)
+        return m_inheritorID.get();
+    return createInheritorID();
+}
+
+inline bool JSCell::isObject(const ClassInfo* info) const
+{
+    for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
+        if (ci == info)
+            return true;
+    }
+    return false;
+}
+
+// this method is here to be after the inline declaration of JSCell::isObject
+inline bool JSValue::isObject(const ClassInfo* classInfo) const
+{
+    return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);
+}
+
+ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (JSValue** location = getDirectLocation(propertyName)) {
+        if (m_structureID->hasGetterSetterProperties() && location[0]->isGetterSetter())
+            fillGetterPropertySlot(slot, location);
+        else
+            slot.setValueSlot(this, location, offsetForLocation(location));
+        return true;
+    }
+
+    // non-standard Netscape extension
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        slot.setValue(prototype());
+        return true;
+    }
+
+    return false;
+}
+
+ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+{
+    unsigned attributes;
+    if (JSValue** location = getDirectLocation(propertyName, attributes)) {
+        if (m_structureID->hasGetterSetterProperties() && location[0]->isGetterSetter()) {
+            slotIsWriteable = false;
+            fillGetterPropertySlot(slot, location);
+        } else {
+            slotIsWriteable = !(attributes & ReadOnly);
+            slot.setValueSlot(this, location, offsetForLocation(location));
+        }
+        return true;
+    }
+
+    // non-standard Netscape extension
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        slot.setValue(prototype());
+        slotIsWriteable = false;
+        return true;
+    }
+
+    return false;
+}
+
+// It may seem crazy to inline a function this large, especially a virtual function,
+// but it makes a big difference to property lookup that derived classes can inline their
+// base class call to this.
+ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    return inlineGetOwnPropertySlot(exec, propertyName, slot);
+}
+
+ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (structureID()->typeInfo().hasStandardGetOwnPropertySlot())
+        return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
+    return getOwnPropertySlot(exec, propertyName, slot);
+}
+
+// It may seem crazy to inline a function this large but it makes a big difference
+// since this is function very hot in variable lookup
+inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    JSObject* object = this;
+    while (true) {
+        if (object->fastGetOwnPropertySlot(exec, propertyName, slot))
+            return true;
+        JSValue* prototype = object->prototype();
+        if (!prototype->isObject())
+            return false;
+        object = asObject(prototype);
+    }
+}
+
+inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    JSObject* object = this;
+    while (true) {
+        if (object->getOwnPropertySlot(exec, propertyName, slot))
+            return true;
+        JSValue* prototype = object->prototype();
+        if (!prototype->isObject())
+            return false;
+        object = asObject(prototype);
+    }
+}
+
+inline JSValue* JSObject::get(ExecState* exec, const Identifier& propertyName) const
+{
+    PropertySlot slot(this);
+    if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
+        return slot.getValue(exec, propertyName);
+    
+    return jsUndefined();
+}
+
+inline JSValue* JSObject::get(ExecState* exec, unsigned propertyName) const
+{
+    PropertySlot slot(this);
+    if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
+        return slot.getValue(exec, propertyName);
+
+    return jsUndefined();
+}
+
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr)
+{
+    PutPropertySlot slot;
+    putDirect(propertyName, value, attr, false, slot);
+}
+
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    if (m_structureID->isDictionary()) {
+        unsigned currentAttributes;
+        size_t offset = m_structureID->get(propertyName, currentAttributes);
+        if (offset != WTF::notFound) {
+            if (checkReadOnly && currentAttributes & ReadOnly)
+                return;
+            m_propertyStorage[offset] = value;
+            slot.setExistingProperty(this, offset);
+            return;
+        }
+
+        size_t currentCapacity = m_structureID->propertyStorageCapacity();
+        offset = m_structureID->addPropertyWithoutTransition(propertyName, attributes);
+        if (currentCapacity != m_structureID->propertyStorageCapacity())
+            allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
+
+        ASSERT(offset < m_structureID->propertyStorageCapacity());
+        m_propertyStorage[offset] = value;
+        slot.setNewProperty(this, offset);
+        return;
+    }
+
+    unsigned currentAttributes;
+    size_t offset = m_structureID->get(propertyName, currentAttributes);
+    if (offset != WTF::notFound) {
+        if (checkReadOnly && currentAttributes & ReadOnly)
+            return;
+        m_propertyStorage[offset] = value;
+        slot.setExistingProperty(this, offset);
+        return;
+    }
+
+    size_t currentCapacity = m_structureID->propertyStorageCapacity();
+    RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, attributes, offset);
+    if (currentCapacity != structureID->propertyStorageCapacity())
+        allocatePropertyStorage(currentCapacity, structureID->propertyStorageCapacity());
+
+    ASSERT(offset < structureID->propertyStorageCapacity());
+    m_propertyStorage[offset] = value;
+    slot.setNewProperty(this, offset);
+    slot.setWasTransition(true);
+    setStructureID(structureID.release());
+}
+
+inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    size_t currentCapacity = m_structureID->propertyStorageCapacity();
+    size_t offset = m_structureID->addPropertyWithoutTransition(propertyName, attributes);
+    if (currentCapacity != m_structureID->propertyStorageCapacity())
+        allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
+    m_propertyStorage[offset] = value;
+}
+
+inline void JSObject::transitionTo(StructureID* newStructureID)
+{
+    if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity())
+        allocatePropertyStorage(m_structureID->propertyStorageCapacity(), newStructureID->propertyStorageCapacity());
+    setStructureID(newStructureID);
+}
+
+inline JSValue* JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+{
+    return defaultValue(exec, preferredType);
+}
+
+inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const
+{
+    PropertySlot slot(this);
+    return get(exec, propertyName, slot);
+}
+
+inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
+{
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
+        if (!prototype->getPropertySlot(exec, propertyName, slot))
+            return jsUndefined();
+        return slot.getValue(exec, propertyName);
+    }
+    JSCell* cell = asCell();
+    while (true) {
+        if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
+            return slot.getValue(exec, propertyName);
+        ASSERT(cell->isObject());
+        JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
+        if (!prototype->isObject())
+            return jsUndefined();
+        cell = asObject(prototype);
+    }
+}
+
+inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const
+{
+    PropertySlot slot(this);
+    return get(exec, propertyName, slot);
+}
+
+inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
+{
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
+        if (!prototype->getPropertySlot(exec, propertyName, slot))
+            return jsUndefined();
+        return slot.getValue(exec, propertyName);
+    }
+    JSCell* cell = const_cast<JSCell*>(asCell());
+    while (true) {
+        if (cell->getOwnPropertySlot(exec, propertyName, slot))
+            return slot.getValue(exec, propertyName);
+        ASSERT(cell->isObject());
+        JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
+        if (!prototype->isObject())
+            return jsUndefined();
+        cell = prototype->asCell();
+    }
+}
+
+inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
+        return;
+    }
+    asCell()->put(exec, propertyName, value, slot);
+}
+
+inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
+{
+    if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
+        return;
+    }
+    asCell()->put(exec, propertyName, value);
+}
+
+ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_t newSize)
+{
+    ASSERT(newSize > oldSize);
+
+    JSValue** oldPropertyStorage = m_propertyStorage;
+    m_propertyStorage = new JSValue*[newSize];
+
+    for (unsigned i = 0; i < oldSize; ++i)
+        m_propertyStorage[i] = oldPropertyStorage[i];
+
+    if (oldPropertyStorage != m_inlineStorage)
+        delete [] oldPropertyStorage;
+}
+
+} // namespace JSC
+
+#endif // JSObject_h
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
new file mode 100644
index 0000000..55f4ced
--- /dev/null
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSPropertyNameIterator.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
+
+JSPropertyNameIterator::~JSPropertyNameIterator()
+{
+}
+
+JSValue* JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+    ASSERT_NOT_REACHED();
+    return noValue();
+}
+
+bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue*&)
+{
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool JSPropertyNameIterator::toBoolean(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+double JSPropertyNameIterator::toNumber(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+UString JSPropertyNameIterator::toString(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return "";
+}
+
+JSObject* JSPropertyNameIterator::toObject(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+void JSPropertyNameIterator::mark()
+{
+    JSCell::mark();
+    if (m_object && !m_object->marked())
+        m_object->mark();
+}
+
+void JSPropertyNameIterator::invalidate()
+{
+    ASSERT(m_position == m_end);
+    m_object = 0;
+    m_data.clear();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h
new file mode 100644
index 0000000..1853999
--- /dev/null
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 JSPropertyNameIterator_h
+#define JSPropertyNameIterator_h
+
+#include "JSObject.h"
+#include "JSString.h"
+#include "PropertyNameArray.h"
+
+namespace JSC {
+
+    class Identifier;
+    class JSObject;
+
+    class JSPropertyNameIterator : public JSCell {
+    public:
+        static JSPropertyNameIterator* create(ExecState*, JSValue*);
+
+        virtual ~JSPropertyNameIterator();
+
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double&, JSValue*&);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+
+        virtual void mark();
+
+        JSValue* next(ExecState*);
+        void invalidate();
+
+    private:
+        JSPropertyNameIterator();
+        JSPropertyNameIterator(JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData);
+
+        JSObject* m_object;
+        RefPtr<PropertyNameArrayData> m_data;
+        PropertyNameArrayData::const_iterator m_position;
+        PropertyNameArrayData::const_iterator m_end;
+    };
+
+inline JSPropertyNameIterator::JSPropertyNameIterator()
+    : JSCell(0)
+    , m_object(0)
+    , m_position(0)
+    , m_end(0)
+{
+}
+
+inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData)
+    : JSCell(0)
+    , m_object(object)
+    , m_data(propertyNameArrayData)
+    , m_position(m_data->begin())
+    , m_end(m_data->end())
+{
+}
+
+inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v)
+{
+    if (v->isUndefinedOrNull())
+        return new (exec) JSPropertyNameIterator;
+
+    JSObject* o = v->toObject(exec);
+    PropertyNameArray propertyNames(exec);
+    o->getPropertyNames(exec, propertyNames);
+    return new (exec) JSPropertyNameIterator(o, propertyNames.releaseData());
+}
+
+inline JSValue* JSPropertyNameIterator::next(ExecState* exec)
+{
+    if (m_position == m_end)
+        return noValue();
+
+    if (m_data->cachedStructureID() == m_object->structureID() && structureIDChainsAreEqual(m_data->cachedPrototypeChain(), m_object->structureID()->cachedPrototypeChain()))
+        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 noValue();
+}
+
+} // namespace JSC
+
+#endif // JSPropertyNameIterator_h
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
new file mode 100644
index 0000000..0698250
--- /dev/null
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#include "JSStaticScopeObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject);
+
+void JSStaticScopeObject::mark()
+{
+    JSVariableObject::mark();
+    
+    if (!d()->registerStore.marked())
+        d()->registerStore.mark();
+}
+
+JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
+{
+    return exec->globalThisValue();
+}
+
+void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&)
+{
+    if (symbolTablePut(propertyName, value))
+        return;
+    
+    ASSERT_NOT_REACHED();
+}
+
+void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    if (symbolTablePutWithAttributes(propertyName, value, attributes))
+        return;
+    
+    ASSERT_NOT_REACHED();
+}
+
+bool JSStaticScopeObject::isDynamicScope() const
+{
+    return false;
+}
+
+JSStaticScopeObject::~JSStaticScopeObject()
+{
+    ASSERT(d());
+    delete d();
+}
+
+inline bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot& slot)
+{
+    return symbolTableGet(propertyName, slot);
+}
+
+inline bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+{
+    return symbolTableGet(propertyName, slot, slotIsWriteable);
+}
+
+}
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h
new file mode 100644
index 0000000..b152862
--- /dev/null
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSStaticScopeObject_h
+#define JSStaticScopeObject_h
+
+#include "JSVariableObject.h"
+
+namespace JSC{
+    
+    class JSStaticScopeObject : public JSVariableObject {
+    protected:
+        using JSVariableObject::JSVariableObjectData;
+        struct JSStaticScopeObjectData : public JSVariableObjectData {
+            JSStaticScopeObjectData()
+                : JSVariableObjectData(&symbolTable, &registerStore + 1)
+            {
+            }
+            SymbolTable symbolTable;
+            Register registerStore;
+        };
+        
+    public:
+        JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue* value, unsigned attributes)
+            : JSVariableObject(exec->globalData().staticScopeStructureID, new JSStaticScopeObjectData())
+        {
+            d()->registerStore = value;
+            symbolTable().add(ident.ustring().rep(), SymbolTableEntry(-1, attributes));
+        }
+        virtual ~JSStaticScopeObject();
+        virtual void mark();
+        bool isDynamicScope() const;
+        virtual JSObject* toThisObject(ExecState*) const;
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
+        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
+        void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+
+    private:
+        JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
+    };
+
+}
+
+#endif // JSStaticScopeObject_h
diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp
new file mode 100644
index 0000000..49503d5
--- /dev/null
+++ b/JavaScriptCore/runtime/JSString.cpp
@@ -0,0 +1,152 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSString.h"
+
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+#include "StringObject.h"
+#include "StringPrototype.h"
+
+namespace JSC {
+
+JSValue* JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+    return const_cast<JSString*>(this);
+}
+
+bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
+{
+    value = this;
+    number = m_value.toDouble();
+    return false;
+}
+
+bool JSString::toBoolean(ExecState*) const
+{
+    return !m_value.isEmpty();
+}
+
+double JSString::toNumber(ExecState*) const
+{
+    return m_value.toDouble();
+}
+
+UString JSString::toString(ExecState*) const
+{
+    return m_value;
+}
+
+UString JSString::toThisString(ExecState*) const
+{
+    return m_value;
+}
+
+JSString* JSString::toThisJSString(ExecState*)
+{
+    return this;
+}
+
+inline StringObject* StringObject::create(ExecState* exec, JSString* string)
+{
+    return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
+}
+
+JSObject* JSString::toObject(ExecState* exec) const
+{
+    return StringObject::create(exec, const_cast<JSString*>(this));
+}
+
+JSObject* JSString::toThisObject(ExecState* exec) const
+{
+    return StringObject::create(exec, const_cast<JSString*>(this));
+}
+
+bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    // The semantics here are really getPropertySlot, not getOwnPropertySlot.
+    // This function should only be called by JSValue::get.
+    if (getStringPropertySlot(exec, propertyName, slot))
+        return true;
+    slot.setBase(this);
+    JSObject* object;
+    for (JSValue* prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype->isNull(); prototype = object->prototype()) {
+        object = asObject(prototype);
+        if (object->getOwnPropertySlot(exec, propertyName, slot))
+            return true;
+    }
+    slot.setUndefined();
+    return true;
+}
+
+bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    // The semantics here are really getPropertySlot, not getOwnPropertySlot.
+    // This function should only be called by JSValue::get.
+    if (getStringPropertySlot(exec, propertyName, slot))
+        return true;
+    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
new file mode 100644
index 0000000..b6275e7
--- /dev/null
+++ b/JavaScriptCore/runtime/JSString.h
@@ -0,0 +1,214 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSString_h
+#define JSString_h
+
+#include "CommonIdentifiers.h"
+#include "ExecState.h"
+#include "JSNumberCell.h"
+#include "PropertySlot.h"
+#include "identifier.h"
+
+namespace JSC {
+
+    class JSString;
+
+    JSString* jsEmptyString(JSGlobalData*);
+    JSString* jsEmptyString(ExecState*);
+    JSString* jsString(JSGlobalData*, const UString&); // returns empty string if passed null string
+    JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string
+
+    JSString* jsSingleCharacterString(JSGlobalData*, UChar);
+    JSString* jsSingleCharacterString(ExecState*, UChar);
+    JSString* jsSingleCharacterSubstring(JSGlobalData*, const UString&, unsigned offset);
+    JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset);
+    JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length);
+    JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length);
+
+    // Non-trivial strings are two or more characters long.
+    // These functions are faster than just calling jsString.
+    JSString* jsNontrivialString(JSGlobalData*, const UString&);
+    JSString* jsNontrivialString(ExecState*, const UString&);
+    JSString* jsNontrivialString(JSGlobalData*, const char*);
+    JSString* jsNontrivialString(ExecState*, const char*);
+
+    // Should be used for strings that are owned by an object that will
+    // likely outlive the JSValue this makes, such as the parse tree or a
+    // DOM object that contains a UString
+    JSString* jsOwnedString(JSGlobalData*, const UString&); 
+    JSString* jsOwnedString(ExecState*, const UString&); 
+
+    class JSString : public JSCell {
+        friend class CTI;
+        friend class Machine;
+
+    public:
+        JSString(JSGlobalData* globalData, const UString& value)
+            : JSCell(globalData->stringStructureID.get())
+            , m_value(value)
+        {
+            Heap::heap(this)->reportExtraMemoryCost(value.cost());
+        }
+
+        enum HasOtherOwnerType { HasOtherOwner };
+        JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
+            : JSCell(globalData->stringStructureID.get())
+            , m_value(value)
+        {
+        }
+        JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
+            : JSCell(globalData->stringStructureID.get())
+            , m_value(value)
+        {
+        }
+        
+        const UString& value() const { return m_value; }
+
+        bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+        bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
+        JSString* getIndex(JSGlobalData*, unsigned);
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
+
+    private:
+        enum VPtrStealingHackType { VPtrStealingHack };
+        JSString(VPtrStealingHackType) 
+            : JSCell(0)
+        {
+        }
+
+        virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+
+        virtual JSObject* toThisObject(ExecState*) const;
+        virtual UString toThisString(ExecState*) const;
+        virtual JSString* toThisJSString(ExecState*);
+
+        // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+        UString m_value;
+    };
+
+    JSString* asString(JSValue*);
+
+    inline JSString* asString(JSValue* value)
+    {
+        ASSERT(asCell(value)->isString());
+        return static_cast<JSString*>(asCell(value));
+    }
+
+    inline JSString* jsEmptyString(JSGlobalData* globalData)
+    {
+        return globalData->smallStrings.emptyString(globalData);
+    }
+
+    inline JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c)
+    {
+        if (c <= 0xFF)
+            return globalData->smallStrings.singleCharacterString(globalData, c);
+        return new (globalData) JSString(globalData, UString(&c, 1));
+    }
+
+    inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset)
+    {
+        ASSERT(offset < static_cast<unsigned>(s.size()));
+        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, 1));
+    }
+
+    inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
+    {
+        ASSERT(s);
+        ASSERT(s[0]);
+        ASSERT(s[1]);
+        return new (globalData) JSString(globalData, s);
+    }
+
+    inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s)
+    {
+        ASSERT(s.size() > 1);
+        return new (globalData) JSString(globalData, s);
+    }
+
+    inline JSString* JSString::getIndex(JSGlobalData* globalData, unsigned i)
+    {
+        ASSERT(canGetIndex(i));
+        return jsSingleCharacterSubstring(globalData, m_value, i);
+    }
+
+    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); }
+    inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) { return jsSingleCharacterSubstring(&exec->globalData(), s, offset); }
+    inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); }
+    inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); }
+    inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); }
+    inline JSString* jsOwnedString(ExecState* exec, const UString& s) { return jsOwnedString(&exec->globalData(), s); } 
+
+    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+    {
+        if (propertyName == exec->propertyNames().length) {
+            slot.setValue(jsNumber(exec, m_value.size()));
+            return true;
+        }
+
+        bool isStrictUInt32;
+        unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
+        if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
+            slot.setValue(jsSingleCharacterSubstring(exec, m_value, i));
+            return true;
+        }
+
+        return false;
+    }
+        
+    ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+    {
+        if (propertyName < static_cast<unsigned>(m_value.size())) {
+            slot.setValue(jsSingleCharacterSubstring(exec, m_value, propertyName));
+            return true;
+        }
+
+        return false;
+    }
+
+    // --- JSValue inlines ----------------------------
+
+    inline JSString* JSValue::toThisJSString(ExecState* exec)
+    {
+        return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec);
+    }
+
+} // namespace JSC
+
+#endif // JSString_h
diff --git a/JavaScriptCore/runtime/JSType.h b/JavaScriptCore/runtime/JSType.h
new file mode 100644
index 0000000..f0fa28f
--- /dev/null
+++ b/JavaScriptCore/runtime/JSType.h
@@ -0,0 +1,43 @@
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 2006 Apple Computer, Inc
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef KJS_JSTYPE_H
+#define KJS_JSTYPE_H
+
+namespace JSC {
+
+    /**
+     * Primitive types
+     */
+    enum JSType {
+        UnspecifiedType   = 0,
+        UndefinedType     = 1,
+        BooleanType       = 2,
+        NumberType        = 3,
+        NullType          = 4,
+        StringType        = 5,
+        ObjectType        = 6,
+        GetterSetterType  = 7
+    };
+
+} // namespace JSC
+
+#endif
diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp
new file mode 100644
index 0000000..73580b0
--- /dev/null
+++ b/JavaScriptCore/runtime/JSValue.cpp
@@ -0,0 +1,104 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSValue.h"
+
+#include "JSFunction.h"
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+static const double D32 = 4294967296.0;
+
+// ECMA 9.4
+double JSValue::toInteger(ExecState* exec) const
+{
+    int32_t i;
+    if (getTruncatedInt32(i))
+        return i;
+    double d = toNumber(exec);
+    return isnan(d) ? 0.0 : trunc(d);
+}
+
+double JSValue::toIntegerPreserveNaN(ExecState* exec) const
+{
+    int32_t i;
+    if (getTruncatedInt32(i))
+        return i;
+    return trunc(toNumber(exec));
+}
+
+int32_t toInt32SlowCase(double d, bool& ok)
+{
+    ok = true;
+
+    if (d >= -D32 / 2 && d < D32 / 2)
+        return static_cast<int32_t>(d);
+
+    if (isnan(d) || isinf(d)) {
+        ok = false;
+        return 0;
+    }
+
+    double d32 = fmod(trunc(d), D32);
+    if (d32 >= D32 / 2)
+        d32 -= D32;
+    else if (d32 < -D32 / 2)
+        d32 += D32;
+    return static_cast<int32_t>(d32);
+}
+
+int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
+{
+    return JSC::toInt32SlowCase(toNumber(exec), ok);
+}
+
+uint32_t toUInt32SlowCase(double d, bool& ok)
+{
+    ok = true;
+
+    if (d >= 0.0 && d < D32)
+        return static_cast<uint32_t>(d);
+
+    if (isnan(d) || isinf(d)) {
+        ok = false;
+        return 0;
+    }
+
+    double d32 = fmod(trunc(d), D32);
+    if (d32 < 0)
+        d32 += D32;
+    return static_cast<uint32_t>(d32);
+}
+
+uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
+{
+    return JSC::toUInt32SlowCase(toNumber(exec), ok);
+}
+
+float JSValue::toFloat(ExecState* exec) const
+{
+    return static_cast<float>(toNumber(exec));
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
new file mode 100644
index 0000000..059a5e6
--- /dev/null
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -0,0 +1,243 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSValue_h
+#define JSValue_h
+
+#include "CallData.h"
+#include "ConstructData.h"
+#include "JSImmediate.h"
+#include "ustring.h"
+#include <stddef.h> // for size_t
+
+// The magic number 0x4000 is not important here, it is being subtracted back out (avoiding using zero since this
+// can have unexpected effects in this type of macro, particularly where multiple-inheritance is involved).
+#define OBJECT_OFFSET(class, member) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->member)) - 0x4000)
+
+namespace JSC {
+
+    class Identifier;
+    class JSString;
+    class PropertySlot;
+    class PutPropertySlot;
+
+    struct ClassInfo;
+    struct Instruction;
+
+    enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
+
+    class JSValue : Noncopyable {
+    protected:
+        JSValue() { }
+        virtual ~JSValue() { }
+
+    public:
+        // Querying the type.
+        bool isUndefined() const;
+        bool isNull() const;
+        bool isUndefinedOrNull() const;
+        bool isBoolean() const;
+        bool isNumber() const;
+        bool isString() const;
+        bool isGetterSetter() const;
+        bool isObject() const;
+        bool isObject(const ClassInfo*) const;
+        
+        // Extracting the value.
+        bool getBoolean(bool&) const;
+        bool getBoolean() const; // false if not a boolean
+        double getNumber() const; // NaN if not a number
+        double uncheckedGetNumber() const;
+        bool getString(UString&) const;
+        UString getString() const; // null string if not a string
+        JSObject* getObject() const; // 0 if not an object
+
+        CallType getCallData(CallData&);
+        ConstructType getConstructData(ConstructData&);
+
+        // Extracting integer values.
+        bool getUInt32(uint32_t&) const;
+        bool getTruncatedInt32(int32_t&) const;
+        bool getTruncatedUInt32(uint32_t&) const;
+        
+        // Basic conversions.
+        JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
+        bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
+
+        bool toBoolean(ExecState*) const;
+
+        // toNumber conversion is expected to be side effect free if an exception has
+        // been set in the ExecState already.
+        double toNumber(ExecState*) const;
+        JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
+
+        UString toString(ExecState*) const;
+        JSObject* toObject(ExecState*) const;
+
+        // Integer conversions.
+        double toInteger(ExecState*) const;
+        double toIntegerPreserveNaN(ExecState*) const;
+        int32_t toInt32(ExecState*) const;
+        int32_t toInt32(ExecState*, bool& ok) const;
+        uint32_t toUInt32(ExecState*) const;
+        uint32_t toUInt32(ExecState*, bool& ok) const;
+
+        // Floating point conversions.
+        float toFloat(ExecState*) const;
+
+        // Garbage collection.
+        void mark();
+        bool marked() const;
+
+        // Object operations, with the toObject operation included.
+        JSValue* get(ExecState*, const Identifier& propertyName) const;
+        JSValue* get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
+        JSValue* get(ExecState*, unsigned propertyName) const;
+        JSValue* get(ExecState*, unsigned propertyName, PropertySlot&) const;
+        void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        void put(ExecState*, unsigned propertyName, JSValue*);
+        bool deleteProperty(ExecState*, const Identifier& propertyName);
+        bool deleteProperty(ExecState*, unsigned propertyName);
+
+        bool needsThisConversion() const;
+        JSObject* toThisObject(ExecState*) const;
+        UString toThisString(ExecState*) const;
+        JSString* toThisJSString(ExecState*);
+
+        JSValue* getJSNumber(); // 0 if this is not a JSNumber or number object
+
+        JSValue* asValue() const;
+
+        JSCell* asCell() const;
+
+    private:
+        bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+        int32_t toInt32SlowCase(ExecState*, bool& ok) const;
+        uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
+    };
+
+    // These are identical logic to the JSValue functions above, and faster than jsNumber(number)->toInt32().
+    int32_t toInt32(double);
+    uint32_t toUInt32(double);
+    int32_t toInt32SlowCase(double, bool& ok);
+    uint32_t toUInt32SlowCase(double, bool& ok);
+
+    inline JSValue* JSValue::asValue() const
+    {
+        return const_cast<JSValue*>(this);
+    }
+
+    inline bool JSValue::isUndefined() const
+    {
+        return asValue() == jsUndefined();
+    }
+
+    inline bool JSValue::isNull() const
+    {
+        return asValue() == jsNull();
+    }
+
+    inline bool JSValue::isUndefinedOrNull() const
+    {
+        return JSImmediate::isUndefinedOrNull(asValue());
+    }
+
+    inline bool JSValue::isBoolean() const
+    {
+        return JSImmediate::isBoolean(asValue());
+    }
+
+    inline bool JSValue::getBoolean(bool& v) const
+    {
+        if (JSImmediate::isBoolean(asValue())) {
+            v = JSImmediate::toBoolean(asValue());
+            return true;
+        }
+        
+        return false;
+    }
+
+    inline bool JSValue::getBoolean() const
+    {
+        return asValue() == jsBoolean(true);
+    }
+
+    ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
+    {
+        int32_t i;
+        if (getTruncatedInt32(i))
+            return i;
+        bool ok;
+        return toInt32SlowCase(exec, ok);
+    }
+
+    inline uint32_t JSValue::toUInt32(ExecState* exec) const
+    {
+        uint32_t i;
+        if (getTruncatedUInt32(i))
+            return i;
+        bool ok;
+        return toUInt32SlowCase(exec, ok);
+    }
+
+    inline int32_t toInt32(double val)
+    {
+        if (!(val >= -2147483648.0 && val < 2147483648.0)) {
+            bool ignored;
+            return toInt32SlowCase(val, ignored);
+        }
+        return static_cast<int32_t>(val);
+    }
+
+    inline uint32_t toUInt32(double val)
+    {
+        if (!(val >= 0.0 && val < 4294967296.0)) {
+            bool ignored;
+            return toUInt32SlowCase(val, ignored);
+        }
+        return static_cast<uint32_t>(val);
+    }
+
+    inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
+    {
+        int32_t i;
+        if (getTruncatedInt32(i)) {
+            ok = true;
+            return i;
+        }
+        return toInt32SlowCase(exec, ok);
+    }
+
+    inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
+    {
+        uint32_t i;
+        if (getTruncatedUInt32(i)) {
+            ok = true;
+            return i;
+        }
+        return toUInt32SlowCase(exec, ok);
+    }
+
+} // namespace JSC
+
+#endif // JSValue_h
diff --git a/JavaScriptCore/runtime/JSVariableObject.cpp b/JavaScriptCore/runtime/JSVariableObject.cpp
new file mode 100644
index 0000000..a36cefa
--- /dev/null
+++ b/JavaScriptCore/runtime/JSVariableObject.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSVariableObject.h"
+
+#include "PropertyNameArray.h"
+
+namespace JSC {
+
+bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    if (symbolTable().contains(propertyName.ustring().rep()))
+        return false;
+
+    return JSObject::deleteProperty(exec, propertyName);
+}
+
+void JSVariableObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+{
+    SymbolTable::const_iterator end = symbolTable().end();
+    for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
+        if (!(it->second.getAttributes() & DontEnum))
+            propertyNames.add(Identifier(exec, it->first.get()));
+    }
+    
+    JSObject::getPropertyNames(exec, propertyNames);
+}
+
+bool JSVariableObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+{
+    SymbolTableEntry entry = symbolTable().get(propertyName.ustring().rep());
+    if (!entry.isNull()) {
+        attributes = entry.getAttributes() | DontDelete;
+        return true;
+    }
+    return JSObject::getPropertyAttributes(exec, propertyName, attributes);
+}
+
+bool JSVariableObject::isVariableObject() const
+{
+    return true;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSVariableObject.h b/JavaScriptCore/runtime/JSVariableObject.h
new file mode 100644
index 0000000..1194517
--- /dev/null
+++ b/JavaScriptCore/runtime/JSVariableObject.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 JSVariableObject_h
+#define JSVariableObject_h
+
+#include "JSObject.h"
+#include "Register.h"
+#include "SymbolTable.h"
+#include "UnusedParam.h"
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/UnusedParam.h>
+
+namespace JSC {
+
+    class Register;
+
+    class JSVariableObject : public JSObject {
+    public:
+        SymbolTable& symbolTable() const { return *d->symbolTable; }
+
+        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes) = 0;
+
+        virtual bool deleteProperty(ExecState*, const Identifier&);
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+        
+        virtual bool isVariableObject() const;
+        virtual bool isDynamicScope() const = 0;
+
+        virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+
+        Register& registerAt(int index) const { return d->registers[index]; }
+
+    protected:
+        // 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).
+        struct JSVariableObjectData {
+            JSVariableObjectData(SymbolTable* symbolTable, Register* registers)
+                : symbolTable(symbolTable)
+                , registers(registers)
+            {
+                ASSERT(symbolTable);
+            }
+
+            SymbolTable* symbolTable; // Maps name -> offset from "r" in register file.
+            Register* registers; // "r" in the register file.
+            OwnArrayPtr<Register> registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
+
+            static inline ptrdiff_t offsetOf_registers()
+            {
+                return OBJECT_OFFSET(JSVariableObjectData, registers);
+            }
+
+        private:
+            JSVariableObjectData(const JSVariableObjectData&);
+            JSVariableObjectData& operator=(const JSVariableObjectData&);
+        };
+
+        JSVariableObject(PassRefPtr<StructureID> structureID, JSVariableObjectData* data)
+            : JSObject(structureID)
+            , d(data) // Subclass owns this pointer.
+        {
+        }
+
+        Register* copyRegisterArray(Register* src, size_t count);
+        void setRegisters(Register* r, Register* registerArray);
+
+        bool symbolTableGet(const Identifier&, PropertySlot&);
+        bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
+        bool symbolTablePut(const Identifier&, JSValue*);
+        bool symbolTablePutWithAttributes(const Identifier&, JSValue*, unsigned attributes);
+
+        JSVariableObjectData* d;
+
+    public:
+        static inline ptrdiff_t offsetOf_d()
+        {
+            return OBJECT_OFFSET(JSVariableObject, d);
+        }
+
+        static inline ptrdiff_t offsetOf_Data_registers()
+        {
+            return JSVariableObjectData::offsetOf_registers();
+        }
+    };
+
+    inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
+    {
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
+        if (!entry.isNull()) {
+            slot.setRegisterSlot(&registerAt(entry.getIndex()));
+            return true;
+        }
+        return false;
+    }
+
+    inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+    {
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
+        if (!entry.isNull()) {
+            slot.setRegisterSlot(&registerAt(entry.getIndex()));
+            slotIsWriteable = !entry.isReadOnly();
+            return true;
+        }
+        return false;
+    }
+
+    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value)
+    {
+        ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
+        if (entry.isNull())
+            return false;
+        if (entry.isReadOnly())
+            return true;
+        registerAt(entry.getIndex()) = value;
+        return true;
+    }
+
+    inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue* value, unsigned attributes)
+    {
+        ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+        SymbolTable::iterator iter = symbolTable().find(propertyName.ustring().rep());
+        if (iter == symbolTable().end())
+            return false;
+        SymbolTableEntry& entry = iter->second;
+        ASSERT(!entry.isNull());
+        entry.setAttributes(attributes);
+        registerAt(entry.getIndex()) = value;
+        return true;
+    }
+
+    inline Register* JSVariableObject::copyRegisterArray(Register* src, size_t count)
+    {
+        Register* registerArray = new Register[count];
+        memcpy(registerArray, src, count * sizeof(Register));
+
+        return registerArray;
+    }
+
+    inline void JSVariableObject::setRegisters(Register* registers, Register* registerArray)
+    {
+        ASSERT(registerArray != d->registerArray.get());
+        d->registerArray.set(registerArray);
+        d->registers = registers;
+    }
+
+} // namespace JSC
+
+#endif // JSVariableObject_h
diff --git a/JavaScriptCore/runtime/JSWrapperObject.cpp b/JavaScriptCore/runtime/JSWrapperObject.cpp
new file mode 100644
index 0000000..c791d93
--- /dev/null
+++ b/JavaScriptCore/runtime/JSWrapperObject.cpp
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2006 Maks Orlovich
+ *  Copyright (C) 2006 Apple Computer, Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSWrapperObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject);
+
+void JSWrapperObject::mark() 
+{
+    JSObject::mark();
+    if (m_internalValue && !m_internalValue->marked())
+        m_internalValue->mark();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSWrapperObject.h b/JavaScriptCore/runtime/JSWrapperObject.h
new file mode 100644
index 0000000..5e4ba17
--- /dev/null
+++ b/JavaScriptCore/runtime/JSWrapperObject.h
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2006 Maks Orlovich
+ *  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.
+ *
+ */
+
+#ifndef KJS_JSWrapperObject_h
+#define KJS_JSWrapperObject_h
+
+#include "JSObject.h"
+
+namespace JSC {
+    
+    // This class is used as a base for classes such as String,
+    // Number, Boolean and Date which are wrappers for primitive types.
+    class JSWrapperObject : public JSObject {
+    protected:
+        explicit JSWrapperObject(PassRefPtr<StructureID>);
+
+    public:
+        JSValue* internalValue() const { return m_internalValue; }
+        void setInternalValue(JSValue*);
+        
+        virtual void mark();
+        
+    private:
+        JSValue* m_internalValue;
+    };
+    
+    inline JSWrapperObject::JSWrapperObject(PassRefPtr<StructureID> structure)
+        : JSObject(structure)
+        , m_internalValue(noValue())
+    {
+    }
+    
+    inline void JSWrapperObject::setInternalValue(JSValue* value)
+    {
+        ASSERT(value);
+        ASSERT(!value->isObject());
+        m_internalValue = value;
+    }
+
+} // namespace JSC
+
+#endif // KJS_JSWrapperObject_h
diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp
new file mode 100644
index 0000000..8b972d3
--- /dev/null
+++ b/JavaScriptCore/runtime/MathObject.cpp
@@ -0,0 +1,247 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "MathObject.h"
+
+#include "ObjectPrototype.h"
+#include "operations.h"
+#include <time.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(MathObject);
+
+static JSValue* mathProtoFuncAbs(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncACos(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncASin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncATan(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncATan2(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncCeil(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncCos(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncExp(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncFloor(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncLog(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncMax(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncMin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncPow(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncRandom(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncRound(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncSin(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncSqrt(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* mathProtoFuncTan(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "MathObject.lut.h"
+
+namespace JSC {
+
+// ------------------------------ MathObject --------------------------------
+
+const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable };
+
+/* Source for MathObject.lut.h
+@begin mathTable
+  abs           mathProtoFuncAbs               DontEnum|Function 1
+  acos          mathProtoFuncACos              DontEnum|Function 1
+  asin          mathProtoFuncASin              DontEnum|Function 1
+  atan          mathProtoFuncATan              DontEnum|Function 1
+  atan2         mathProtoFuncATan2             DontEnum|Function 2
+  ceil          mathProtoFuncCeil              DontEnum|Function 1
+  cos           mathProtoFuncCos               DontEnum|Function 1
+  exp           mathProtoFuncExp               DontEnum|Function 1
+  floor         mathProtoFuncFloor             DontEnum|Function 1
+  log           mathProtoFuncLog               DontEnum|Function 1
+  max           mathProtoFuncMax               DontEnum|Function 2
+  min           mathProtoFuncMin               DontEnum|Function 2
+  pow           mathProtoFuncPow               DontEnum|Function 2
+  random        mathProtoFuncRandom            DontEnum|Function 0 
+  round         mathProtoFuncRound             DontEnum|Function 1
+  sin           mathProtoFuncSin               DontEnum|Function 1
+  sqrt          mathProtoFuncSqrt              DontEnum|Function 1
+  tan           mathProtoFuncTan               DontEnum|Function 1
+@end
+*/
+
+MathObject::MathObject(ExecState* exec, PassRefPtr<StructureID> structure)
+    : JSObject(structure)
+{
+    putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exec, exp(1.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "LN2"), jsNumber(exec, log(2.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "LN10"), jsNumber(exec, log(10.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "LOG2E"), jsNumber(exec, 1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "LOG10E"), jsNumber(exec, 1.0 / log(10.0)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "PI"), jsNumber(exec, piDouble), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "SQRT1_2"), jsNumber(exec, sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(Identifier(exec, "SQRT2"), jsNumber(exec, sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
+}
+
+// ECMA 15.8
+
+bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
+{
+    const HashEntry* entry = ExecState::mathTable(exec)->entry(exec, propertyName);
+
+    if (!entry)
+        return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+
+    ASSERT(entry->attributes() & Function);
+    setUpStaticFunctionSlot(exec, entry, this, propertyName, slot);
+    return true;
+}
+
+// ------------------------------ Functions --------------------------------
+
+JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, fabs(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, acos(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, asin(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, atan(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, atan2(args.at(exec, 0)->toNumber(exec), args.at(exec, 1)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, ceil(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, cos(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, exp(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, floor(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, log(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    unsigned argsCount = args.size();
+    double result = -Inf;
+    for (unsigned k = 0; k < argsCount; ++k) {
+        double val = args.at(exec, k)->toNumber(exec);
+        if (isnan(val)) {
+            result = NaN;
+            break;
+        }
+        if (val > result || (val == 0 && result == 0 && !signbit(val)))
+            result = val;
+    }
+    return jsNumber(exec, result);
+}
+
+JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    unsigned argsCount = args.size();
+    double result = +Inf;
+    for (unsigned k = 0; k < argsCount; ++k) {
+        double val = args.at(exec, k)->toNumber(exec);
+        if (isnan(val)) {
+            result = NaN;
+            break;
+        }
+        if (val < result || (val == 0 && result == 0 && signbit(val)))
+            result = val;
+    }
+    return jsNumber(exec, result);
+}
+
+JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    // ECMA 15.8.2.1.13
+
+    double arg = args.at(exec, 0)->toNumber(exec);
+    double arg2 = args.at(exec, 1)->toNumber(exec);
+
+    if (isnan(arg2))
+        return jsNaN(exec);
+    if (isinf(arg2) && fabs(arg) == 1)
+        return jsNaN(exec);
+    return jsNumber(exec, pow(arg, arg2));
+}
+
+JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+{
+#if !ENABLE(JSC_MULTIPLE_THREADS)
+    static bool didInitRandom;
+    if (!didInitRandom) {
+        wtf_random_init();
+        didInitRandom = true;
+    }
+#endif
+
+    return jsNumber(exec, wtf_random());
+}
+
+JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    double arg = args.at(exec, 0)->toNumber(exec);
+    if (signbit(arg) && arg >= -0.5)
+         return jsNumber(exec, -0.0);
+    return jsNumber(exec, floor(arg + 0.5));
+}
+
+JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, sin(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, sqrt(args.at(exec, 0)->toNumber(exec)));
+}
+
+JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, tan(args.at(exec, 0)->toNumber(exec)));
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/MathObject.h b/JavaScriptCore/runtime/MathObject.h
new file mode 100644
index 0000000..704b10e
--- /dev/null
+++ b/JavaScriptCore/runtime/MathObject.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef MathObject_h
+#define MathObject_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class MathObject : public JSObject {
+    public:
+        MathObject(ExecState*, PassRefPtr<StructureID>);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+    };
+
+} // namespace JSC
+
+#endif // MathObject_h
diff --git a/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/JavaScriptCore/runtime/NativeErrorConstructor.cpp
new file mode 100644
index 0000000..05159f0
--- /dev/null
+++ b/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "NativeErrorConstructor.h"
+
+#include "ErrorInstance.h"
+#include "JSFunction.h"
+#include "NativeErrorPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
+
+const ClassInfo NativeErrorConstructor::info = { "Function", &InternalFunction::info, 0, 0 };
+
+NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<StructureID> structure, NativeErrorPrototype* nativeErrorPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name)->getString()))
+    , m_errorStructure(ErrorInstance::createStructureID(nativeErrorPrototype))
+{
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
+    putDirect(exec->propertyNames().prototype, nativeErrorPrototype, DontDelete | ReadOnly | DontEnum);
+}
+
+ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
+{
+    ErrorInstance* object = new (exec) ErrorInstance(m_errorStructure);
+    if (!args.at(exec, 0)->isUndefined())
+        object->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0)->toString(exec)));
+    return object;
+}
+
+static JSObject* constructWithNativeErrorConstructor(ExecState* exec, JSObject* constructor, const ArgList& args)
+{
+    return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
+}
+
+ConstructType NativeErrorConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithNativeErrorConstructor;
+    return ConstructTypeHost;
+}
+
+static JSValue* callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValue*, const ArgList& args)
+{
+    return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
+}
+
+CallType NativeErrorConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callNativeErrorConstructor;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/NativeErrorConstructor.h b/JavaScriptCore/runtime/NativeErrorConstructor.h
new file mode 100644
index 0000000..85acbb9
--- /dev/null
+++ b/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef NativeErrorConstructor_h
+#define NativeErrorConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class ErrorInstance;
+    class FunctionPrototype;
+    class NativeErrorPrototype;
+
+    class NativeErrorConstructor : public InternalFunction {
+    public:
+        NativeErrorConstructor(ExecState*, PassRefPtr<StructureID>, NativeErrorPrototype*);
+
+        static const ClassInfo info;
+
+        ErrorInstance* construct(ExecState*, const ArgList&);
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        RefPtr<StructureID> m_errorStructure;
+    };
+
+} // namespace JSC
+
+#endif // NativeErrorConstructor_h
diff --git a/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/JavaScriptCore/runtime/NativeErrorPrototype.cpp
new file mode 100644
index 0000000..9403aa9
--- /dev/null
+++ b/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 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 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 "NativeErrorPrototype.h"
+
+#include "ErrorPrototype.h"
+#include "JSString.h"
+#include "ustring.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
+
+NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, PassRefPtr<StructureID> structure, const UString& name, const UString& message)
+    : JSObject(structure)
+{
+    putDirect(exec->propertyNames().name, jsString(exec, name), 0);
+    putDirect(exec->propertyNames().message, jsString(exec, message), 0);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/NativeErrorPrototype.h b/JavaScriptCore/runtime/NativeErrorPrototype.h
new file mode 100644
index 0000000..719cb90
--- /dev/null
+++ b/JavaScriptCore/runtime/NativeErrorPrototype.h
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef NativeErrorPrototype_h
+#define NativeErrorPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class NativeErrorPrototype : public JSObject {
+    public:
+        NativeErrorPrototype(ExecState*, PassRefPtr<StructureID>, const UString& name, const UString& message);
+    };
+
+} // namespace JSC
+
+#endif // NativeErrorPrototype_h
diff --git a/JavaScriptCore/runtime/NumberConstructor.cpp b/JavaScriptCore/runtime/NumberConstructor.cpp
new file mode 100644
index 0000000..5b6ccf8
--- /dev/null
+++ b/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "NumberConstructor.h"
+
+#include "NumberObject.h"
+#include "NumberPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
+
+static JSValue* numberConstructorNaNValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* numberConstructorNegInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* numberConstructorPosInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* numberConstructorMaxValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* numberConstructorMinValue(ExecState*, const Identifier&, const PropertySlot&);
+
+} // namespace JSC
+
+#include "NumberConstructor.lut.h"
+
+namespace JSC {
+
+const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable };
+
+/* Source for NumberConstructor.lut.h
+@begin numberTable
+   NaN                   numberConstructorNaNValue       DontEnum|DontDelete|ReadOnly
+   NEGATIVE_INFINITY     numberConstructorNegInfinity    DontEnum|DontDelete|ReadOnly
+   POSITIVE_INFINITY     numberConstructorPosInfinity    DontEnum|DontDelete|ReadOnly
+   MAX_VALUE             numberConstructorMaxValue       DontEnum|DontDelete|ReadOnly
+   MIN_VALUE             numberConstructorMinValue       DontEnum|DontDelete|ReadOnly
+@end
+*/
+
+NumberConstructor::NumberConstructor(ExecState* exec, PassRefPtr<StructureID> structure, NumberPrototype* numberPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, numberPrototype->info.className))
+{
+    // Number.Prototype
+    putDirectWithoutTransition(exec->propertyNames().prototype, numberPrototype, DontEnum | DontDelete | ReadOnly);
+
+    // no. of arguments for constructor
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
+}
+
+bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
+}
+
+JSValue* numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+    return jsNaN(exec);
+}
+
+JSValue* numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+    return jsNumberCell(exec, -Inf);
+}
+
+JSValue* numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+    return jsNumberCell(exec, Inf);
+}
+
+JSValue* numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+    return jsNumberCell(exec, 1.7976931348623157E+308);
+}
+
+JSValue* numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+    return jsNumberCell(exec, 5E-324);
+}
+
+// ECMA 15.7.1
+static JSObject* constructWithNumberConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
+    double n = args.isEmpty() ? 0 : args.at(exec, 0)->toNumber(exec);
+    object->setInternalValue(jsNumber(exec, n));
+    return object;
+}
+
+ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithNumberConstructor;
+    return ConstructTypeHost;
+}
+
+// ECMA 15.7.2
+static JSValue* callNumberConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return jsNumber(exec, args.isEmpty() ? 0 : args.at(exec, 0)->toNumber(exec));
+}
+
+CallType NumberConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callNumberConstructor;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/NumberConstructor.h b/JavaScriptCore/runtime/NumberConstructor.h
new file mode 100644
index 0000000..8da23c4
--- /dev/null
+++ b/JavaScriptCore/runtime/NumberConstructor.h
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef NumberConstructor_h
+#define NumberConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class NumberPrototype;
+
+    class NumberConstructor : public InternalFunction {
+    public:
+        NumberConstructor(ExecState*, PassRefPtr<StructureID>, NumberPrototype*);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+        JSValue* getValueProperty(ExecState*, int token) const;
+
+        static const ClassInfo info;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto) 
+        { 
+            return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance)); 
+        }
+
+        enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+    };
+
+} // namespace JSC
+
+#endif // NumberConstructor_h
diff --git a/JavaScriptCore/runtime/NumberObject.cpp b/JavaScriptCore/runtime/NumberObject.cpp
new file mode 100644
index 0000000..252671b
--- /dev/null
+++ b/JavaScriptCore/runtime/NumberObject.cpp
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "NumberObject.h"
+
+#include "JSGlobalObject.h"
+#include "NumberPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NumberObject);
+
+const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
+
+NumberObject::NumberObject(PassRefPtr<StructureID> structure)
+    : JSWrapperObject(structure)
+{
+}
+
+JSValue* NumberObject::getJSNumber()
+{
+    return internalValue();
+}
+
+NumberObject* constructNumber(ExecState* exec, JSNumberCell* number)
+{
+    NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
+    object->setInternalValue(number);
+    return object;
+}
+
+NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValue* value)
+{
+    NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
+    object->setInternalValue(value);
+    return object;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h
new file mode 100644
index 0000000..eddecd1
--- /dev/null
+++ b/JavaScriptCore/runtime/NumberObject.h
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef NumberObject_h
+#define NumberObject_h
+
+#include "JSWrapperObject.h"
+
+namespace JSC {
+
+    class JSNumberCell;
+
+    class NumberObject : public JSWrapperObject {
+    public:
+        explicit NumberObject(PassRefPtr<StructureID>);
+
+        static const ClassInfo info;
+
+    private:
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        virtual JSValue* getJSNumber();
+    };
+
+    NumberObject* constructNumber(ExecState*, JSNumberCell*);
+    NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValue*);
+
+} // namespace JSC
+
+#endif // NumberObject_h
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
new file mode 100644
index 0000000..d203e3f
--- /dev/null
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -0,0 +1,441 @@
+/*
+ *  Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "NumberPrototype.h"
+
+#include "Error.h"
+#include "JSString.h"
+#include "PrototypeFunction.h"
+#include "dtoa.h"
+#include "operations.h"
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NumberPrototype);
+
+static JSValue* numberProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+// ECMA 15.7.4
+
+NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+    : NumberObject(structure)
+{
+    setInternalValue(jsNumber(exec, 0));
+
+    // The constructor will be added later, after NumberConstructor has been constructed
+
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
+}
+
+// ------------------------------ Functions ---------------------------
+
+// ECMA 15.7.4.2 - 15.7.4.7
+
+static UString integerPartNoExp(double d)
+{
+    int decimalPoint;
+    int sign;
+    char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
+    bool resultIsInfOrNan = (decimalPoint == 9999);
+    size_t length = strlen(result);
+
+    UString str = sign ? "-" : "";
+    if (resultIsInfOrNan)
+        str += result;
+    else if (decimalPoint <= 0)
+        str += "0";
+    else {
+        Vector<char, 1024> buf(decimalPoint + 1);
+
+        if (static_cast<int>(length) <= decimalPoint) {
+            strcpy(buf.data(), result);
+            memset(buf.data() + length, '0', decimalPoint - length);
+        } else
+            strncpy(buf.data(), result, decimalPoint);
+
+        buf[decimalPoint] = '\0';
+        str.append(buf.data());
+    }
+
+    freedtoa(result);
+
+    return str;
+}
+
+static UString charSequence(char c, int count)
+{
+    Vector<char, 2048> buf(count + 1, c);
+    buf[count] = '\0';
+
+    return UString(buf.data());
+}
+
+static double intPow10(int e)
+{
+    // This function uses the "exponentiation by squaring" algorithm and
+    // long double to quickly and precisely calculate integer powers of 10.0.
+
+    // This is a handy workaround for <rdar://problem/4494756>
+
+    if (e == 0)
+        return 1.0;
+
+    bool negative = e < 0;
+    unsigned exp = negative ? -e : e;
+
+    long double result = 10.0;
+    bool foundOne = false;
+    for (int bit = 31; bit >= 0; bit--) {
+        if (!foundOne) {
+            if ((exp >> bit) & 1)
+                foundOne = true;
+        } else {
+            result = result * result;
+            if ((exp >> bit) & 1)
+                result = result * 10.0;
+        }
+    }
+
+    if (negative)
+        return static_cast<double>(1.0 / result);
+    return static_cast<double>(result);
+}
+
+JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSValue* v = thisValue->getJSNumber();
+    if (!v)
+        return throwError(exec, TypeError);
+
+    double radixAsDouble = args.at(exec, 0)->toInteger(exec); // nan -> 0
+    if (radixAsDouble == 10 || args.at(exec, 0)->isUndefined())
+        return jsString(exec, v->toString(exec));
+
+    if (radixAsDouble < 2 || radixAsDouble > 36)
+        return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
+
+    int radix = static_cast<int>(radixAsDouble);
+    const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+    // INT_MAX results in 1024 characters left of the dot with radix 2
+    // give the same space on the right side. safety checks are in place
+    // unless someone finds a precise rule.
+    char s[2048 + 3];
+    const char* lastCharInString = s + sizeof(s) - 1;
+    double x = v->uncheckedGetNumber();
+    if (isnan(x) || isinf(x))
+        return jsString(exec, UString::from(x));
+
+    bool isNegative = x < 0.0;
+    if (isNegative)
+        x = -x;
+
+    double integerPart = floor(x);
+    char* decimalPoint = s + sizeof(s) / 2;
+
+    // convert integer portion
+    char* p = decimalPoint;
+    double d = integerPart;
+    do {
+        int remainderDigit = static_cast<int>(fmod(d, radix));
+        *--p = digits[remainderDigit];
+        d /= radix;
+    } while ((d <= -1.0 || d >= 1.0) && s < p);
+
+    if (isNegative)
+        *--p = '-';
+    char* startOfResultString = p;
+    ASSERT(s <= startOfResultString);
+
+    d = x - integerPart;
+    p = decimalPoint;
+    const double epsilon = 0.001; // TODO: guessed. base on radix ?
+    bool hasFractionalPart = (d < -epsilon || d > epsilon);
+    if (hasFractionalPart) {
+        *p++ = '.';
+        do {
+            d *= radix;
+            const int digit = static_cast<int>(d);
+            *p++ = digits[digit];
+            d -= digit;
+        } while ((d < -epsilon || d > epsilon) && p < lastCharInString);
+    }
+    *p = '\0';
+    ASSERT(p < s + sizeof(s));
+
+    return jsString(exec, startOfResultString);
+}
+
+JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    // FIXME: Not implemented yet.
+
+    JSValue* v = thisValue->getJSNumber();
+    if (!v)
+        return throwError(exec, TypeError);
+
+    return jsString(exec, v->toString(exec));
+}
+
+JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    JSValue* v = thisValue->getJSNumber();
+    if (!v)
+        return throwError(exec, TypeError);
+
+    return v;
+}
+
+JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSValue* v = thisValue->getJSNumber();
+    if (!v)
+        return throwError(exec, TypeError);
+
+    JSValue* fractionDigits = args.at(exec, 0);
+    double df = fractionDigits->toInteger(exec);
+    if (!(df >= 0 && df <= 20))
+        return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20");
+    int f = static_cast<int>(df);
+
+    double x = v->uncheckedGetNumber();
+    if (isnan(x))
+        return jsNontrivialString(exec, "NaN");
+
+    UString s;
+    if (x < 0) {
+        s.append('-');
+        x = -x;
+    } else if (x == -0.0)
+        x = 0;
+
+    if (x >= pow(10.0, 21.0))
+        return jsString(exec, s + UString::from(x));
+
+    const double tenToTheF = pow(10.0, f);
+    double n = floor(x * tenToTheF);
+    if (fabs(n / tenToTheF - x) >= fabs((n + 1) / tenToTheF - x))
+        n++;
+
+    UString m = integerPartNoExp(n);
+
+    int k = m.size();
+    if (k <= f) {
+        UString z;
+        for (int i = 0; i < f + 1 - k; i++)
+            z.append('0');
+        m = z + m;
+        k = f + 1;
+        ASSERT(k == m.size());
+    }
+    int kMinusf = k - f;
+    if (kMinusf < m.size())
+        return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
+    return jsString(exec, s + m.substr(0, kMinusf));
+}
+
+static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
+{
+    if (fractionalDigits <= 0)
+        return;
+
+    int fDigitsInResult = static_cast<int>(resultLength) - 1;
+    buf[i++] = '.';
+    if (fDigitsInResult > 0) {
+        if (fractionalDigits < fDigitsInResult) {
+            strncpy(buf + i, result + 1, fractionalDigits);
+            i += fractionalDigits;
+        } else {
+            strcpy(buf + i, result + 1);
+            i += static_cast<int>(resultLength) - 1;
+        }
+    }
+
+    for (int j = 0; j < fractionalDigits - fDigitsInResult; j++)
+        buf[i++] = '0';
+}
+
+static void exponentialPartToString(char* buf, int& i, int decimalPoint)
+{
+    buf[i++] = 'e';
+    // decimalPoint can't be more than 3 digits decimal given the
+    // nature of float representation
+    int exponential = decimalPoint - 1;
+    buf[i++] = (exponential >= 0) ? '+' : '-';
+    if (exponential < 0)
+        exponential *= -1;
+    if (exponential >= 100)
+        buf[i++] = static_cast<char>('0' + exponential / 100);
+    if (exponential >= 10)
+        buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
+    buf[i++] = static_cast<char>('0' + exponential % 10);
+}
+
+JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSValue* v = thisValue->getJSNumber();
+    if (!v)
+        return throwError(exec, TypeError);
+
+    double x = v->uncheckedGetNumber();
+
+    if (isnan(x) || isinf(x))
+        return jsString(exec, UString::from(x));
+
+    JSValue* fractionalDigitsValue = args.at(exec, 0);
+    double df = fractionalDigitsValue->toInteger(exec);
+    if (!(df >= 0 && df <= 20))
+        return throwError(exec, RangeError, "toExponential() argument must between 0 and 20");
+    int fractionalDigits = static_cast<int>(df);
+    bool includeAllDigits = fractionalDigitsValue->isUndefined();
+
+    int decimalAdjust = 0;
+    if (x && !includeAllDigits) {
+        double logx = floor(log10(fabs(x)));
+        x /= pow(10.0, logx);
+        const double tenToTheF = pow(10.0, fractionalDigits);
+        double fx = floor(x * tenToTheF) / tenToTheF;
+        double cx = ceil(x * tenToTheF) / tenToTheF;
+
+        if (fabs(fx - x) < fabs(cx - x))
+            x = fx;
+        else
+            x = cx;
+
+        decimalAdjust = static_cast<int>(logx);
+    }
+
+    if (isnan(x))
+        return jsNontrivialString(exec, "NaN");
+
+    if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0
+        x = 0;
+
+    int decimalPoint;
+    int sign;
+    char* result = dtoa(x, 0, &decimalPoint, &sign, NULL);
+    size_t resultLength = strlen(result);
+    decimalPoint += decimalAdjust;
+
+    int i = 0;
+    char buf[80]; // digit + '.' + fractionDigits (max 20) + 'e' + sign + exponent (max?)
+    if (sign)
+        buf[i++] = '-';
+
+    if (decimalPoint == 999) // ? 9999 is the magical "result is Inf or NaN" value.  what's 999??
+        strcpy(buf + i, result);
+    else {
+        buf[i++] = result[0];
+
+        if (includeAllDigits)
+            fractionalDigits = static_cast<int>(resultLength) - 1;
+
+        fractionalPartToString(buf, i, result, resultLength, fractionalDigits);
+        exponentialPartToString(buf, i, decimalPoint);
+        buf[i++] = '\0';
+    }
+    ASSERT(i <= 80);
+
+    freedtoa(result);
+
+    return jsString(exec, buf);
+}
+
+JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSValue* v = thisValue->getJSNumber();
+    if (!v)
+        return throwError(exec, TypeError);
+
+    double doublePrecision = args.at(exec, 0)->toIntegerPreserveNaN(exec);
+    double x = v->uncheckedGetNumber();
+    if (args.at(exec, 0)->isUndefined() || isnan(x) || isinf(x))
+        return jsString(exec, v->toString(exec));
+
+    UString s;
+    if (x < 0) {
+        s = "-";
+        x = -x;
+    }
+
+    if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
+        return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21");
+    int precision = static_cast<int>(doublePrecision);
+
+    int e = 0;
+    UString m;
+    if (x) {
+        e = static_cast<int>(log10(x));
+        double tens = intPow10(e - precision + 1);
+        double n = floor(x / tens);
+        if (n < intPow10(precision - 1)) {
+            e = e - 1;
+            tens = intPow10(e - precision + 1);
+            n = floor(x / tens);
+        }
+
+        if (fabs((n + 1.0) * tens - x) <= fabs(n * tens - x))
+            ++n;
+        // maintain n < 10^(precision)
+        if (n >= intPow10(precision)) {
+            n /= 10.0;
+            e += 1;
+        }
+        ASSERT(intPow10(precision - 1) <= n);
+        ASSERT(n < intPow10(precision));
+
+        m = integerPartNoExp(n);
+        if (e < -6 || e >= precision) {
+            if (m.size() > 1)
+                m = m.substr(0, 1) + "." + m.substr(1);
+            if (e >= 0)
+                return jsNontrivialString(exec, s + m + "e+" + UString::from(e));
+            return jsNontrivialString(exec, s + m + "e-" + UString::from(-e));
+        }
+    } else {
+        m = charSequence('0', precision);
+        e = 0;
+    }
+
+    if (e == precision - 1)
+        return jsString(exec, s + m);
+    if (e >= 0) {
+        if (e + 1 < m.size())
+            return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
+        return jsString(exec, s + m);
+    }
+    return jsNontrivialString(exec, s + "0." + charSequence('0', -(e + 1)) + m);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/NumberPrototype.h b/JavaScriptCore/runtime/NumberPrototype.h
new file mode 100644
index 0000000..d70f260
--- /dev/null
+++ b/JavaScriptCore/runtime/NumberPrototype.h
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef NumberPrototype_h
+#define NumberPrototype_h
+
+#include "NumberObject.h"
+
+namespace JSC {
+
+    class NumberPrototype : public NumberObject {
+    public:
+        NumberPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+    };
+
+} // namespace JSC
+
+#endif // NumberPrototype_h
diff --git a/JavaScriptCore/runtime/ObjectConstructor.cpp b/JavaScriptCore/runtime/ObjectConstructor.cpp
new file mode 100644
index 0000000..329816f
--- /dev/null
+++ b/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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 "ObjectConstructor.h"
+
+#include "JSGlobalObject.h"
+#include "ObjectPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
+
+ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<StructureID> structure, ObjectPrototype* objectPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object"))
+{
+    // ECMA 15.2.3.1
+    putDirectWithoutTransition(exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly);
+
+    // no. of arguments for constructor
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
+}
+
+// ECMA 15.2.2
+static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
+{
+    JSValue* arg = args.at(exec, 0);
+    if (arg->isUndefinedOrNull())
+        return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
+    return arg->toObject(exec);
+}
+
+static JSObject* constructWithObjectConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructObject(exec, args);
+}
+
+ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithObjectConstructor;
+    return ConstructTypeHost;
+}
+
+static JSValue* callObjectConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructObject(exec, args);
+}
+
+CallType ObjectConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callObjectConstructor;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ObjectConstructor.h b/JavaScriptCore/runtime/ObjectConstructor.h
new file mode 100644
index 0000000..c100424
--- /dev/null
+++ b/JavaScriptCore/runtime/ObjectConstructor.h
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef ObjectConstructor_h
+#define ObjectConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class ObjectPrototype;
+
+    class ObjectConstructor : public InternalFunction {
+    public:
+        ObjectConstructor(ExecState*, PassRefPtr<StructureID>, ObjectPrototype*);
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+} // namespace JSC
+
+#endif // ObjectConstructor_h
diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp
new file mode 100644
index 0000000..42a8063
--- /dev/null
+++ b/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -0,0 +1,134 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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 "ObjectPrototype.h"
+
+#include "Error.h"
+#include "JSString.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
+
+static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<StructureID> stucture, StructureID* prototypeFunctionStructure)
+    : JSObject(stucture)
+{
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
+
+    // Mozilla extensions
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
+}
+
+// ------------------------------ Functions --------------------------------
+
+// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
+
+JSValue* objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    return thisValue->toThisObject(exec);
+}
+
+JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    return jsBoolean(thisValue->toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(exec, 0)->toString(exec))));
+}
+
+JSValue* objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue->toThisObject(exec);
+
+    if (!args.at(exec, 0)->isObject())
+        return jsBoolean(false);
+
+    JSValue* v = asObject(args.at(exec, 0))->prototype();
+
+    while (true) {
+        if (!v->isObject())
+            return jsBoolean(false);
+        if (thisObj == v)
+            return jsBoolean(true);
+        v = asObject(v)->prototype();
+    }
+}
+
+JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    CallData callData;
+    if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
+        return throwError(exec, SyntaxError, "invalid getter usage");
+    thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
+    return jsUndefined();
+}
+
+JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    CallData callData;
+    if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
+        return throwError(exec, SyntaxError, "invalid setter usage");
+    thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
+    return jsUndefined();
+}
+
+JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    return thisValue->toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)));
+}
+
+JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    return thisValue->toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)));
+}
+
+JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    return jsBoolean(thisValue->toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(exec, 0)->toString(exec))));
+}
+
+JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    return thisValue->toThisJSString(exec);
+}
+
+JSValue* objectProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    return jsNontrivialString(exec, "[object " + thisValue->toThisObject(exec)->className() + "]");
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ObjectPrototype.h b/JavaScriptCore/runtime/ObjectPrototype.h
new file mode 100644
index 0000000..aefdf95
--- /dev/null
+++ b/JavaScriptCore/runtime/ObjectPrototype.h
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef ObjectPrototype_h
+#define ObjectPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class ObjectPrototype : public JSObject {
+    public:
+        ObjectPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+    };
+
+    JSValue* objectProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+} // namespace JSC
+
+#endif // ObjectPrototype_h
diff --git a/JavaScriptCore/runtime/PropertyMapHashTable.h b/JavaScriptCore/runtime/PropertyMapHashTable.h
new file mode 100644
index 0000000..98b0727
--- /dev/null
+++ b/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -0,0 +1,77 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PropertyMapHashTable_h
+#define PropertyMapHashTable_h
+
+#include "ustring.h"
+
+namespace JSC {
+
+    struct PropertyMapEntry {
+        UString::Rep* key;
+        unsigned offset;
+        unsigned attributes;
+        unsigned index;
+
+        PropertyMapEntry(UString::Rep* k, int a)
+            : key(k)
+            , offset(0)
+            , attributes(a)
+            , index(0)
+        {
+        }
+    };
+
+    // lastIndexUsed is an ever-increasing index used to identify the order items
+    // were inserted into the property map. It's required that getEnumerablePropertyNames
+    // return the properties in the order they were added for compatibility with other
+    // browsers' JavaScript implementations.
+    struct PropertyMapHashTable {
+        unsigned sizeMask;
+        unsigned size;
+        unsigned keyCount;
+        unsigned deletedSentinelCount;
+        unsigned lastIndexUsed;
+        unsigned entryIndices[1];
+
+        PropertyMapEntry* entries()
+        {
+            // The entries vector comes after the indices vector.
+            // The 0th item in the entries vector is not really used; it has to
+            // have a 0 in its key to allow the hash table lookup to handle deleted
+            // sentinels without any special-case code, but the other fields are unused.
+            return reinterpret_cast<PropertyMapEntry*>(&entryIndices[size]);
+        }
+
+        static size_t allocationSize(unsigned size)
+        {
+            // We never let a hash table get more than half full,
+            // So the number of indices we need is the size of the hash table.
+            // But the number of entries is half that (plus one for the deleted sentinel).
+            return sizeof(PropertyMapHashTable)
+                + (size - 1) * sizeof(unsigned)
+                + (1 + size / 2) * sizeof(PropertyMapEntry);
+        }
+    };
+
+} // namespace JSC
+
+#endif // PropertyMapHashTable_h
diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp
new file mode 100644
index 0000000..47e9d84
--- /dev/null
+++ b/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -0,0 +1,50 @@
+/*
+ *  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.
+ *
+ */
+
+#include "config.h"
+#include "PropertyNameArray.h"
+
+namespace JSC {
+
+static const size_t setThreshold = 20;
+
+void PropertyNameArray::add(UString::Rep* identifier)
+{
+    ASSERT(identifier == &UString::Rep::null || identifier == &UString::Rep::empty || identifier->identifierTable());
+
+    size_t size = m_data->propertyNameVector().size();
+    if (size < setThreshold) {
+        for (size_t i = 0; i < size; ++i) {
+            if (identifier == m_data->propertyNameVector()[i].ustring().rep())
+                return;
+        }
+    } else {
+        if (m_set.isEmpty()) {
+            for (size_t i = 0; i < size; ++i)
+                m_set.add(m_data->propertyNameVector()[i].ustring().rep());
+        }
+        if (!m_set.add(identifier).second)
+            return;
+    }
+
+    m_data->propertyNameVector().append(Identifier(m_globalData, identifier));
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/PropertyNameArray.h b/JavaScriptCore/runtime/PropertyNameArray.h
new file mode 100644
index 0000000..d19c2e5
--- /dev/null
+++ b/JavaScriptCore/runtime/PropertyNameArray.h
@@ -0,0 +1,112 @@
+/*
+ *  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.
+ *
+ */
+
+#ifndef PropertyNameArray_h
+#define PropertyNameArray_h
+
+#include "ExecState.h"
+#include "StructureID.h"
+#include "identifier.h"
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+    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 setCachedStructureID(StructureID* structureID) { m_cachedStructureID = structureID; }
+        StructureID* cachedStructureID() const { return m_cachedStructureID; }
+
+        void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+        StructureIDChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
+
+    private:
+        PropertyNameArrayData()
+            : m_cachedStructureID(0)
+        {
+        }
+
+        PropertyNameVector m_propertyNameVector;
+        StructureID* m_cachedStructureID;
+        RefPtr<StructureIDChain> m_cachedPrototypeChain;
+    };
+
+    class PropertyNameArray {
+    public:
+        typedef PropertyNameArrayData::const_iterator const_iterator;
+
+        PropertyNameArray(JSGlobalData* globalData)
+            : m_data(PropertyNameArrayData::create())
+            , m_globalData(globalData)
+            , m_cacheable(true)
+        {
+        }
+
+        PropertyNameArray(ExecState* exec)
+            : m_data(PropertyNameArrayData::create())
+            , m_globalData(&exec->globalData())
+            , m_cacheable(true)
+        {
+        }
+
+        JSGlobalData* globalData() { return m_globalData; }
+
+        void add(const Identifier& identifier) { add(identifier.ustring().rep()); }
+        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 setCacheable(bool cacheable) { m_cacheable = cacheable; }
+        bool cacheable() const { return m_cacheable; }
+
+    private:
+        typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
+
+        RefPtr<PropertyNameArrayData> m_data;
+        IdentifierSet m_set;
+        JSGlobalData* m_globalData;
+        bool m_cacheable;
+    };
+
+} // namespace JSC
+
+#endif // PropertyNameArray_h
diff --git a/JavaScriptCore/runtime/PropertySlot.cpp b/JavaScriptCore/runtime/PropertySlot.cpp
new file mode 100644
index 0000000..37df83a
--- /dev/null
+++ b/JavaScriptCore/runtime/PropertySlot.cpp
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "PropertySlot.h"
+
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+
+namespace JSC {
+
+JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    // Prevent getter functions from observing execution if an exception is pending.
+    if (exec->hadException())
+        return exec->exception();
+
+    CallData callData;
+    CallType callType = slot.m_data.getterFunc->getCallData(callData);
+    if (callType == CallTypeHost)
+        return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList());
+    ASSERT(callType == CallTypeJS);
+    // FIXME: Can this be done more efficiently using the callData?
+    return static_cast<JSFunction*>(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList());
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/PropertySlot.h b/JavaScriptCore/runtime/PropertySlot.h
new file mode 100644
index 0000000..29c19d4
--- /dev/null
+++ b/JavaScriptCore/runtime/PropertySlot.h
@@ -0,0 +1,212 @@
+/*
+ *  Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PropertySlot_h
+#define PropertySlot_h
+
+#include "Register.h"
+#include "JSValue.h"
+#include "identifier.h"
+#include <wtf/Assertions.h>
+#include <wtf/NotFound.h>
+
+namespace JSC {
+
+    class ExecState;
+    class JSObject;
+
+#define JSC_VALUE_SLOT_MARKER 0
+#define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
+
+    class PropertySlot {
+    public:
+        PropertySlot()
+            : m_offset(WTF::notFound)
+        {
+            clearBase();
+            clearValue();
+        }
+
+        explicit PropertySlot(const JSValue* base)
+            : m_slotBase(const_cast<JSValue*>(base))
+            , m_offset(WTF::notFound)
+        {
+            clearValue();
+        }
+
+        typedef JSValue* (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
+
+        JSValue* getValue(ExecState* exec, const Identifier& propertyName) const
+        {
+            if (m_getValue == JSC_VALUE_SLOT_MARKER)
+                return *m_data.valueSlot;
+            if (m_getValue == JSC_REGISTER_SLOT_MARKER)
+                return (*m_data.registerSlot).jsValue(exec);
+            return m_getValue(exec, propertyName, *this);
+        }
+
+        JSValue* getValue(ExecState* exec, unsigned propertyName) const
+        {
+            if (m_getValue == JSC_VALUE_SLOT_MARKER)
+                return *m_data.valueSlot;
+            if (m_getValue == JSC_REGISTER_SLOT_MARKER)
+                return (*m_data.registerSlot).jsValue(exec);
+            return m_getValue(exec, Identifier::from(exec, propertyName), *this);
+        }
+
+        bool isCacheable() const { return m_offset != WTF::notFound; }
+        size_t cachedOffset() const
+        {
+            ASSERT(isCacheable());
+            return m_offset;
+        }
+
+        void putValue(JSValue* value)
+        { 
+            if (m_getValue == JSC_VALUE_SLOT_MARKER) {
+                *m_data.valueSlot = value;
+                return;
+            }
+            ASSERT(m_getValue == JSC_REGISTER_SLOT_MARKER);
+            *m_data.registerSlot = value;
+        }
+
+        void setValueSlot(JSValue** valueSlot) 
+        {
+            ASSERT(valueSlot);
+            m_getValue = JSC_VALUE_SLOT_MARKER;
+            clearBase();
+            m_data.valueSlot = valueSlot;
+        }
+        
+        void setValueSlot(JSValue* slotBase, JSValue** valueSlot)
+        {
+            ASSERT(valueSlot);
+            m_getValue = JSC_VALUE_SLOT_MARKER;
+            m_slotBase = slotBase;
+            m_data.valueSlot = valueSlot;
+        }
+        
+        void setValueSlot(JSValue* slotBase, JSValue** valueSlot, size_t offset)
+        {
+            ASSERT(valueSlot);
+            m_getValue = JSC_VALUE_SLOT_MARKER;
+            m_slotBase = slotBase;
+            m_data.valueSlot = valueSlot;
+            m_offset = offset;
+        }
+        
+        void setValue(JSValue* value)
+        {
+            ASSERT(value);
+            m_getValue = JSC_VALUE_SLOT_MARKER;
+            clearBase();
+            m_value = value;
+            m_data.valueSlot = &m_value;
+        }
+
+        void setRegisterSlot(Register* registerSlot)
+        {
+            ASSERT(registerSlot);
+            m_getValue = JSC_REGISTER_SLOT_MARKER;
+            clearBase();
+            m_data.registerSlot = registerSlot;
+        }
+
+        void setCustom(JSValue* slotBase, GetValueFunc getValue)
+        {
+            ASSERT(slotBase);
+            ASSERT(getValue);
+            m_getValue = getValue;
+            m_slotBase = slotBase;
+        }
+
+        void setCustomIndex(JSValue* slotBase, unsigned index, GetValueFunc getValue)
+        {
+            ASSERT(slotBase);
+            ASSERT(getValue);
+            m_getValue = getValue;
+            m_slotBase = slotBase;
+            m_data.index = index;
+        }
+        
+        void setGetterSlot(JSObject* getterFunc)
+        {
+            ASSERT(getterFunc);
+            m_getValue = functionGetter;
+            m_data.getterFunc = getterFunc;
+        }
+        
+        void setUndefined()
+        {
+            clearBase();
+            setValue(jsUndefined());
+        }
+
+        JSValue* slotBase() const
+        {
+            ASSERT(m_slotBase);
+            return m_slotBase;
+        }
+
+        void setBase(JSValue* base)
+        {
+            ASSERT(m_slotBase);
+            ASSERT(base);
+            m_slotBase = base;
+        }
+
+        void clearBase()
+        {
+#ifndef NDEBUG
+            m_slotBase = noValue();
+#endif
+        }
+
+        void clearValue()
+        {
+#ifndef NDEBUG
+            m_value = noValue();
+#endif
+        }
+
+        unsigned index() const { return m_data.index; }
+
+    private:
+        static JSValue* functionGetter(ExecState*, const Identifier&, const PropertySlot&);
+
+        GetValueFunc m_getValue;
+        
+        JSValue* m_slotBase;
+        union {
+            JSObject* getterFunc;
+            JSValue** valueSlot;
+            Register* registerSlot;
+            unsigned index;
+        } m_data;
+
+        JSValue* m_value;
+
+        size_t m_offset;
+    };
+
+} // namespace JSC
+
+#endif // PropertySlot_h
diff --git a/JavaScriptCore/runtime/PrototypeFunction.cpp b/JavaScriptCore/runtime/PrototypeFunction.cpp
new file mode 100644
index 0000000..8afe6a4
--- /dev/null
+++ b/JavaScriptCore/runtime/PrototypeFunction.cpp
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "PrototypeFunction.h"
+
+#include "JSGlobalObject.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(PrototypeFunction);
+
+PrototypeFunction::PrototypeFunction(ExecState* exec, int length, const Identifier& name, NativeFunction function)
+    : InternalFunction(&exec->globalData(), exec->lexicalGlobalObject()->prototypeFunctionStructure(), name)
+    , m_function(function)
+{
+    ASSERT_ARG(function, function);
+    putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+}
+
+PrototypeFunction::PrototypeFunction(ExecState* exec, PassRefPtr<StructureID> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function)
+    : InternalFunction(&exec->globalData(), prototypeFunctionStructure, name)
+    , m_function(function)
+{
+    ASSERT_ARG(function, function);
+    putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+}
+    
+CallType PrototypeFunction::getCallData(CallData& callData)
+{
+    callData.native.function = m_function;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/PrototypeFunction.h b/JavaScriptCore/runtime/PrototypeFunction.h
new file mode 100644
index 0000000..1592995
--- /dev/null
+++ b/JavaScriptCore/runtime/PrototypeFunction.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *  Copyright (C) 2007 Maks Orlovich
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PrototypeFunction_h
+#define PrototypeFunction_h
+
+#include "InternalFunction.h"
+#include "CallData.h"
+
+namespace JSC {
+
+    class PrototypeFunction : public InternalFunction {
+    public:
+        PrototypeFunction(ExecState*, int length, const Identifier&, NativeFunction);
+        PrototypeFunction(ExecState*, PassRefPtr<StructureID>, int length, const Identifier&, NativeFunction);
+
+    private:
+        virtual CallType getCallData(CallData&);
+
+        const NativeFunction m_function;
+    };
+
+} // namespace JSC
+
+#endif // PrototypeFunction_h
diff --git a/JavaScriptCore/runtime/PutPropertySlot.h b/JavaScriptCore/runtime/PutPropertySlot.h
new file mode 100644
index 0000000..1e2dfe9
--- /dev/null
+++ b/JavaScriptCore/runtime/PutPropertySlot.h
@@ -0,0 +1,81 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 PutPropertySlot_h
+#define PutPropertySlot_h
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+    
+    class JSObject;
+    
+    class PutPropertySlot {
+    public:
+        enum Type { Invalid, ExistingProperty, NewProperty };
+
+        PutPropertySlot()
+            : m_type(Invalid)
+            , m_base(0)
+            , m_wasTransition(false)
+        {
+        }
+
+        void setExistingProperty(JSObject* base, size_t offset)
+        {
+            m_type = ExistingProperty;
+            m_base = base;
+            m_offset = offset;
+        }
+
+        void setNewProperty(JSObject* base, size_t offset)
+        {
+            m_type = NewProperty;
+            m_base = base;
+            m_offset = offset;
+        }
+
+        Type type() const { return m_type; }
+        JSObject* base() const { return m_base; }
+
+        bool isCacheable() const { return m_type != Invalid; }
+        size_t cachedOffset() const {
+            ASSERT(isCacheable());
+            return m_offset;
+        }
+        
+        bool wasTransition() const { return m_wasTransition; }
+        void setWasTransition(bool wasTransition) { m_wasTransition = wasTransition; }
+    private:
+        Type m_type;
+        JSObject* m_base;
+        bool m_wasTransition;
+        size_t m_offset;
+    };
+
+} // namespace JSC
+
+#endif // PutPropertySlot_h
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
new file mode 100644
index 0000000..4c4db39
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -0,0 +1,385 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "RegExpConstructor.h"
+
+#include "ArrayPrototype.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "RegExpMatchesArray.h"
+#include "RegExpObject.h"
+#include "RegExpPrototype.h"
+#include "regexp.h"
+
+namespace JSC {
+
+static JSValue* regExpConstructorInput(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorLastMatch(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorLastParen(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorLeftContext(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorRightContext(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar1(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar2(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar3(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar4(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar5(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar6(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar7(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar8(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpConstructorDollar9(ExecState*, const Identifier&, const PropertySlot&);
+
+static void setRegExpConstructorInput(ExecState*, JSObject*, JSValue*);
+static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue*);
+
+} // namespace JSC
+
+#include "RegExpConstructor.lut.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(RegExpConstructor);
+
+const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::regExpConstructorTable };
+
+/* Source for RegExpConstructor.lut.h
+@begin regExpConstructorTable
+    input           regExpConstructorInput          None
+    $_              regExpConstructorInput          DontEnum
+    multiline       regExpConstructorMultiline      None
+    $*              regExpConstructorMultiline      DontEnum
+    lastMatch       regExpConstructorLastMatch      DontDelete|ReadOnly
+    $&              regExpConstructorLastMatch      DontDelete|ReadOnly|DontEnum
+    lastParen       regExpConstructorLastParen      DontDelete|ReadOnly
+    $+              regExpConstructorLastParen      DontDelete|ReadOnly|DontEnum
+    leftContext     regExpConstructorLeftContext    DontDelete|ReadOnly
+    $`              regExpConstructorLeftContext    DontDelete|ReadOnly|DontEnum
+    rightContext    regExpConstructorRightContext   DontDelete|ReadOnly
+    $'              regExpConstructorRightContext   DontDelete|ReadOnly|DontEnum
+    $1              regExpConstructorDollar1        DontDelete|ReadOnly
+    $2              regExpConstructorDollar2        DontDelete|ReadOnly
+    $3              regExpConstructorDollar3        DontDelete|ReadOnly
+    $4              regExpConstructorDollar4        DontDelete|ReadOnly
+    $5              regExpConstructorDollar5        DontDelete|ReadOnly
+    $6              regExpConstructorDollar6        DontDelete|ReadOnly
+    $7              regExpConstructorDollar7        DontDelete|ReadOnly
+    $8              regExpConstructorDollar8        DontDelete|ReadOnly
+    $9              regExpConstructorDollar9        DontDelete|ReadOnly
+@end
+*/
+
+struct RegExpConstructorPrivate {
+    // Global search cache / settings
+    RegExpConstructorPrivate()
+        : lastNumSubPatterns(0)
+        , multiline(false)
+    {
+    }
+
+    UString input;
+    UString lastInput;
+    OwnArrayPtr<int> lastOvector;
+    unsigned lastNumSubPatterns : 31;
+    bool multiline : 1;
+};
+
+RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<StructureID> structure, RegExpPrototype* regExpPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, "RegExp"))
+    , d(new RegExpConstructorPrivate)
+{
+    // ECMA 15.10.5.1 RegExp.prototype
+    putDirectWithoutTransition(exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);
+
+    // no. of arguments for constructor
+    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)
+{
+    OwnArrayPtr<int> tmpOvector;
+    position = r->match(s, startOffset, &tmpOvector);
+
+    if (ovector)
+        *ovector = tmpOvector.get();
+
+    if (position != -1) {
+        ASSERT(tmpOvector);
+
+        length = tmpOvector[1] - tmpOvector[0];
+
+        d->input = s;
+        d->lastInput = s;
+        d->lastOvector.set(tmpOvector.release());
+        d->lastNumSubPatterns = r->numSubpatterns();
+    }
+}
+
+RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
+    : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1)
+{
+    RegExpConstructorPrivate* d = new RegExpConstructorPrivate;
+    d->input = data->lastInput;
+    d->lastInput = data->lastInput;
+    d->lastNumSubPatterns = data->lastNumSubPatterns;
+    unsigned offsetVectorSize = (data->lastNumSubPatterns + 1) * 2; // only copying the result part of the vector
+    d->lastOvector.set(new int[offsetVectorSize]);
+    memcpy(d->lastOvector.get(), data->lastOvector.get(), offsetVectorSize * sizeof(int));
+    // d->multiline is not needed, and remains uninitialized
+
+    setLazyCreationData(d);
+}
+
+RegExpMatchesArray::~RegExpMatchesArray()
+{
+    delete static_cast<RegExpConstructorPrivate*>(lazyCreationData());
+}
+
+void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
+{
+    RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(lazyCreationData());
+    ASSERT(d);
+
+    unsigned lastNumSubpatterns = d->lastNumSubPatterns;
+
+    for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
+        int start = d->lastOvector[2 * i];
+        if (start >= 0)
+            JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start));
+    }
+
+    PutPropertySlot slot;
+    JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]), slot);
+    JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
+
+    delete d;
+    setLazyCreationData(0);
+}
+
+JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
+{
+    return new (exec) RegExpMatchesArray(exec, d.get());
+}
+
+JSValue* RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
+{
+    if (d->lastOvector && i <= d->lastNumSubPatterns) {
+        int start = d->lastOvector[2 * i];
+        if (start >= 0)
+            return jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start);
+    }
+    return jsEmptyString(exec);
+}
+
+JSValue* RegExpConstructor::getLastParen(ExecState* exec) const
+{
+    unsigned i = d->lastNumSubPatterns;
+    if (i > 0) {
+        ASSERT(d->lastOvector);
+        int start = d->lastOvector[2 * i];
+        if (start >= 0)
+            return jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start);
+    }
+    return jsEmptyString(exec);
+}
+
+JSValue* RegExpConstructor::getLeftContext(ExecState* exec) const
+{
+    if (d->lastOvector)
+        return jsSubstring(exec, d->lastInput, 0, d->lastOvector[0]);
+    return jsEmptyString(exec);
+}
+
+JSValue* RegExpConstructor::getRightContext(ExecState* exec) const
+{
+    if (d->lastOvector)
+        return jsSubstring(exec, d->lastInput, d->lastOvector[1], d->lastInput.size() - d->lastOvector[1]);
+    return jsEmptyString(exec);
+}
+    
+bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot);
+}
+
+JSValue* regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1);
+}
+
+JSValue* regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 2);
+}
+
+JSValue* regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 3);
+}
+
+JSValue* regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 4);
+}
+
+JSValue* regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 5);
+}
+
+JSValue* regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 6);
+}
+
+JSValue* regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 7);
+}
+
+JSValue* regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 8);
+}
+
+JSValue* regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 9);
+}
+
+JSValue* regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return jsString(exec, asRegExpConstructor(slot.slotBase())->input());
+}
+
+JSValue* regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+{
+    return jsBoolean(asRegExpConstructor(slot.slotBase())->multiline());
+}
+
+JSValue* regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 0);
+}
+
+JSValue* regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getLastParen(exec);
+}
+
+JSValue* regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getLeftContext(exec);
+}
+
+JSValue* regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return asRegExpConstructor(slot.slotBase())->getRightContext(exec);
+}
+
+void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this, slot);
+}
+
+void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue* value)
+{
+    asRegExpConstructor(baseObject)->setInput(value->toString(exec));
+}
+
+void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue* value)
+{
+    asRegExpConstructor(baseObject)->setMultiline(value->toBoolean(exec));
+}
+  
+// ECMA 15.10.4
+JSObject* constructRegExp(ExecState* exec, const ArgList& args)
+{
+    JSValue* arg0 = args.at(exec, 0);
+    JSValue* arg1 = args.at(exec, 1);
+
+    if (arg0->isObject(&RegExpObject::info)) {
+        if (!arg1->isUndefined())
+            return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
+        return asObject(arg0);
+    }
+
+    UString pattern = arg0->isUndefined() ? UString("") : arg0->toString(exec);
+    UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
+
+    RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
+    if (!regExp->isValid())
+        return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+    return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
+}
+
+static JSObject* constructWithRegExpConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    return constructRegExp(exec, args);
+}
+
+ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithRegExpConstructor;
+    return ConstructTypeHost;
+}
+
+// ECMA 15.10.3
+static JSValue* callRegExpConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    return constructRegExp(exec, args);
+}
+
+CallType RegExpConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callRegExpConstructor;
+    return CallTypeHost;
+}
+
+void RegExpConstructor::setInput(const UString& input)
+{
+    d->input = input;
+}
+
+const UString& RegExpConstructor::input() const
+{
+    // Can detect a distinct initial state that is invisible to JavaScript, by checking for null
+    // state (since jsString turns null strings to empty strings).
+    return d->input;
+}
+
+void RegExpConstructor::setMultiline(bool multiline)
+{
+    d->multiline = multiline;
+}
+
+bool RegExpConstructor::multiline() const
+{
+    return d->multiline;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpConstructor.h b/JavaScriptCore/runtime/RegExpConstructor.h
new file mode 100644
index 0000000..c5a94a5
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpConstructor.h
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef RegExpConstructor_h
+#define RegExpConstructor_h
+
+#include "InternalFunction.h"
+#include <wtf/OwnPtr.h>
+
+namespace JSC {
+
+    class RegExp;
+    class RegExpPrototype;
+    struct RegExpConstructorPrivate;
+
+    class RegExpConstructor : public InternalFunction {
+    public:
+        RegExpConstructor(ExecState*, PassRefPtr<StructureID>, RegExpPrototype*);
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+        }
+
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+
+        static const ClassInfo info;
+
+        void performMatch(RegExp*, const UString&, int startOffset, int& position, int& length, int** ovector = 0);
+        JSObject* arrayOfMatches(ExecState*) const;
+
+        void setInput(const UString&);
+        const UString& input() const;
+
+        void setMultiline(bool);
+        bool multiline() const;
+
+        JSValue* getBackref(ExecState*, unsigned) const;
+        JSValue* getLastParen(ExecState*) const;
+        JSValue* getLeftContext(ExecState*) const;
+        JSValue* getRightContext(ExecState*) const;
+
+    private:
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        OwnPtr<RegExpConstructorPrivate> d;
+    };
+
+    RegExpConstructor* asRegExpConstructor(JSValue*);
+
+    JSObject* constructRegExp(ExecState*, const ArgList&);
+
+    inline RegExpConstructor* asRegExpConstructor(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&RegExpConstructor::info));
+        return static_cast<RegExpConstructor*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // RegExpConstructor_h
diff --git a/JavaScriptCore/runtime/RegExpMatchesArray.h b/JavaScriptCore/runtime/RegExpMatchesArray.h
new file mode 100644
index 0000000..6a4279e
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (C) 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 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
+ *
+ */
+
+#ifndef RegExpMatchesArray_h
+#define RegExpMatchesArray_h
+
+#include "JSArray.h"
+
+namespace JSC {
+
+    class RegExpMatchesArray : public JSArray {
+    public:
+        RegExpMatchesArray(ExecState*, RegExpConstructorPrivate*);
+        virtual ~RegExpMatchesArray();
+
+    private:
+        virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            return JSArray::getOwnPropertySlot(exec, propertyName, slot);
+        }
+
+        virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            return JSArray::getOwnPropertySlot(exec, propertyName, slot);
+        }
+
+        virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v, PutPropertySlot& slot)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            JSArray::put(exec, propertyName, v, slot);
+        }
+
+        virtual void put(ExecState* exec, unsigned propertyName, JSValue* v)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            JSArray::put(exec, propertyName, v);
+        }
+
+        virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            return JSArray::deleteProperty(exec, propertyName);
+        }
+
+        virtual bool deleteProperty(ExecState* exec, unsigned propertyName)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            return JSArray::deleteProperty(exec, propertyName);
+        }
+
+        virtual void getPropertyNames(ExecState* exec, PropertyNameArray& arr)
+        {
+            if (lazyCreationData())
+                fillArrayInstance(exec);
+            JSArray::getPropertyNames(exec, arr);
+        }
+
+        void fillArrayInstance(ExecState*);
+};
+
+}
+
+#endif // RegExpMatchesArray_h
diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp
new file mode 100644
index 0000000..127a71e
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpObject.cpp
@@ -0,0 +1,169 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "RegExpObject.h"
+
+#include "JSArray.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+#include "RegExpConstructor.h"
+#include "RegExpPrototype.h"
+
+namespace JSC {
+
+static JSValue* regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpObjectSource(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue* regExpObjectLastIndex(ExecState*, const Identifier&, const PropertySlot&);
+static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue*);
+
+} // namespace JSC
+
+#include "RegExpObject.lut.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(RegExpObject);
+
+const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable };
+
+/* Source for RegExpObject.lut.h
+@begin regExpTable
+    global        regExpObjectGlobal       DontDelete|ReadOnly|DontEnum
+    ignoreCase    regExpObjectIgnoreCase   DontDelete|ReadOnly|DontEnum
+    multiline     regExpObjectMultiline    DontDelete|ReadOnly|DontEnum
+    source        regExpObjectSource       DontDelete|ReadOnly|DontEnum
+    lastIndex     regExpObjectLastIndex    DontDelete|DontEnum
+@end
+*/
+
+RegExpObject::RegExpObject(PassRefPtr<StructureID> structure, PassRefPtr<RegExp> regExp)
+    : JSObject(structure)
+    , d(new RegExpObjectData(regExp, 0))
+{
+}
+
+RegExpObject::~RegExpObject()
+{
+}
+
+bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
+}
+
+JSValue* regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
+{
+    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
+}
+
+JSValue* regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
+{
+    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
+}
+ 
+JSValue* regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+{            
+    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
+}
+
+JSValue* regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
+}
+
+JSValue* regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+    return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
+}
+
+void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot);
+}
+
+void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue* value)
+{
+    asRegExpObject(baseObject)->setLastIndex(value->toInteger(exec));
+}
+
+bool RegExpObject::match(ExecState* exec, const ArgList& args)
+{
+    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+
+    UString input;
+    if (!args.isEmpty())
+        input = args.at(exec, 0)->toString(exec);
+    else {
+        input = regExpObj->input();
+        if (input.isNull()) {
+            throwError(exec, GeneralError, "No input.");
+            return false;
+        }
+    }
+
+    bool global = get(exec, exec->propertyNames().global)->toBoolean(exec);
+    int lastIndex = 0;
+    if (global) {
+        if (d->lastIndex < 0 || d->lastIndex > input.size()) {
+            d->lastIndex = 0;
+            return false;
+        }
+        lastIndex = static_cast<int>(d->lastIndex);
+    }
+
+    int foundIndex;
+    int foundLength;
+    regExpObj->performMatch(d->regExp.get(), input, lastIndex, foundIndex, foundLength);
+
+    if (global) {
+        lastIndex = foundIndex < 0 ? 0 : foundIndex + foundLength;
+        d->lastIndex = lastIndex;
+    }
+
+    return foundIndex >= 0;
+}
+
+JSValue* RegExpObject::test(ExecState* exec, const ArgList& args)
+{
+    return jsBoolean(match(exec, args));
+}
+
+JSValue* RegExpObject::exec(ExecState* exec, const ArgList& args)
+{
+    if (match(exec, args))
+        return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec);
+    return jsNull();
+}
+
+static JSValue* callRegExpObject(ExecState* exec, JSObject* function, JSValue*, const ArgList& args)
+{
+    return asRegExpObject(function)->exec(exec, args);
+}
+
+CallType RegExpObject::getCallData(CallData& callData)
+{
+    callData.native.function = callRegExpObject;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h
new file mode 100644
index 0000000..d80b47c
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpObject.h
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef RegExpObject_h
+#define RegExpObject_h
+
+#include "JSObject.h"
+#include "regexp.h"
+
+namespace JSC {
+
+    class RegExpObject : public JSObject {
+    public:
+        RegExpObject(PassRefPtr<StructureID>, PassRefPtr<RegExp>);
+        virtual ~RegExpObject();
+
+        void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; }
+        RegExp* regExp() const { return d->regExp.get(); }
+
+        void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
+        double lastIndex() const { return d->lastIndex; }
+
+        JSValue* test(ExecState*, const ArgList&);
+        JSValue* exec(ExecState*, const ArgList&);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+
+    private:
+        bool match(ExecState*, const ArgList&);
+
+        virtual CallType getCallData(CallData&);
+
+        struct RegExpObjectData {
+            RegExpObjectData(PassRefPtr<RegExp> regExp, double lastIndex)
+                : regExp(regExp)
+                , lastIndex(lastIndex)
+            {
+            }
+
+            RefPtr<RegExp> regExp;
+            double lastIndex;
+        };
+
+        OwnPtr<RegExpObjectData> d;
+    };
+
+    RegExpObject* asRegExpObject(JSValue*);
+
+    inline RegExpObject* asRegExpObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&RegExpObject::info));
+        return static_cast<RegExpObject*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // RegExpObject_h
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
new file mode 100644
index 0000000..ceee32a
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -0,0 +1,118 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "RegExpPrototype.h"
+
+#include "ArrayPrototype.h"
+#include "JSArray.h"
+#include "JSObject.h"
+#include "JSString.h"
+#include "JSValue.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+#include "RegExpObject.h"
+#include "regexp.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype);
+
+static JSValue* regExpProtoFuncTest(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* regExpProtoFuncExec(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* regExpProtoFuncCompile(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* regExpProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+// ECMA 15.10.5
+
+const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
+
+RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+    : JSObject(structure)
+{
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
+}
+
+// ------------------------------ Functions ---------------------------
+    
+JSValue* regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&RegExpObject::info))
+        return throwError(exec, TypeError);
+    return asRegExpObject(thisValue)->test(exec, args);
+}
+
+JSValue* regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&RegExpObject::info))
+        return throwError(exec, TypeError);
+    return asRegExpObject(thisValue)->exec(exec, args);
+}
+
+JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (!thisValue->isObject(&RegExpObject::info))
+        return throwError(exec, TypeError);
+
+    RefPtr<RegExp> regExp;
+    JSValue* arg0 = args.at(exec, 0);
+    JSValue* arg1 = args.at(exec, 1);
+    
+    if (arg0->isObject(&RegExpObject::info)) {
+        if (!arg1->isUndefined())
+            return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
+        regExp = asRegExpObject(arg0)->regExp();
+    } else {
+        UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec);
+        UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
+        regExp = RegExp::create(&exec->globalData(), pattern, flags);
+    }
+
+    if (!regExp->isValid())
+        return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+
+    asRegExpObject(thisValue)->setRegExp(regExp.release());
+    asRegExpObject(thisValue)->setLastIndex(0);
+    return jsUndefined();
+}
+
+JSValue* regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    if (!thisValue->isObject(&RegExpObject::info)) {
+        if (thisValue->isObject(&RegExpPrototype::info))
+            return jsNontrivialString(exec, "//");
+        return throwError(exec, TypeError);
+    }
+
+    UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source)->toString(exec);
+    result.append('/');
+    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
+        result.append('g');
+    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
+        result.append('i');
+    if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
+        result.append('m');
+    return jsNontrivialString(exec, result);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpPrototype.h b/JavaScriptCore/runtime/RegExpPrototype.h
new file mode 100644
index 0000000..44a0f32
--- /dev/null
+++ b/JavaScriptCore/runtime/RegExpPrototype.h
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef RegExpPrototype_h
+#define RegExpPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class RegExpPrototype : public JSObject {
+    public:
+        RegExpPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+    };
+
+} // namespace JSC
+
+#endif // RegExpPrototype_h
diff --git a/JavaScriptCore/runtime/ScopeChain.cpp b/JavaScriptCore/runtime/ScopeChain.cpp
new file mode 100644
index 0000000..e90b565
--- /dev/null
+++ b/JavaScriptCore/runtime/ScopeChain.cpp
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (C) 2003, 2006, 2008 Apple Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ScopeChain.h"
+
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+#include "PropertyNameArray.h"
+#include <stdio.h>
+
+namespace JSC {
+
+#ifndef NDEBUG
+
+void ScopeChainNode::print() const
+{
+    ScopeChainIterator scopeEnd = end();
+    for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) {
+        JSObject* o = *scopeIter;
+        PropertyNameArray propertyNames(globalObject()->globalExec());
+        o->getPropertyNames(globalObject()->globalExec(), propertyNames);
+        PropertyNameArray::const_iterator propEnd = propertyNames.end();
+
+        fprintf(stderr, "----- [scope %p] -----\n", o);
+        for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) {
+            Identifier name = *propIter;
+            fprintf(stderr, "%s, ", name.ascii());
+        }
+        fprintf(stderr, "\n");
+    }
+}
+
+#endif
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/ScopeChain.h b/JavaScriptCore/runtime/ScopeChain.h
new file mode 100644
index 0000000..834217c
--- /dev/null
+++ b/JavaScriptCore/runtime/ScopeChain.h
@@ -0,0 +1,218 @@
+/*
+ *  Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ScopeChain_h
+#define ScopeChain_h
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+    class JSGlobalData;
+    class JSGlobalObject;
+    class JSObject;
+    class ScopeChainIterator;
+    
+    class ScopeChainNode {
+    public:
+        ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSObject* globalThis)
+            : next(next)
+            , object(object)
+            , globalData(globalData)
+            , globalThis(globalThis)
+            , refCount(1)
+        {
+            ASSERT(globalData);
+        }
+
+        ScopeChainNode* next;
+        JSObject* object;
+        JSGlobalData* globalData;
+        JSObject* globalThis;
+        int refCount;
+
+        void deref() { if (--refCount == 0) release(); }
+        void ref() { ++refCount; }
+        void release();
+
+        // Before calling "push" on a bare ScopeChainNode, a client should
+        // logically "copy" the node. Later, the client can "deref" the head
+        // of its chain of ScopeChainNodes to reclaim all the nodes it added
+        // after the logical copy, leaving nodes added before the logical copy
+        // (nodes shared with other clients) untouched.
+        ScopeChainNode* copy()
+        {
+            ref();
+            return this;
+        }
+
+        ScopeChainNode* push(JSObject*);
+        ScopeChainNode* pop();
+
+        ScopeChainIterator begin() const;
+        ScopeChainIterator end() const;
+
+        JSGlobalObject* globalObject() const; // defined in JSGlobalObject.h
+        JSObject* globalThisObject() const { return globalThis; }
+
+#ifndef NDEBUG        
+        void print() const;
+#endif
+    };
+
+    inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
+    {
+        ASSERT(o);
+        return new ScopeChainNode(this, o, globalData, globalThis);
+    }
+
+    inline ScopeChainNode* ScopeChainNode::pop()
+    {
+        ASSERT(next);
+        ScopeChainNode* result = next;
+
+        if (--refCount != 0)
+            ++result->refCount;
+        else
+            delete this;
+
+        return result;
+    }
+
+    inline void ScopeChainNode::release()
+    {
+        // This function is only called by deref(),
+        // Deref ensures these conditions are true.
+        ASSERT(refCount == 0);
+        ScopeChainNode* n = this;
+        do {
+            ScopeChainNode* next = n->next;
+            delete n;
+            n = next;
+        } while (n && --n->refCount == 0);
+    }
+
+    class ScopeChainIterator {
+    public:
+        ScopeChainIterator(const ScopeChainNode* node)
+            : m_node(node)
+        {
+        }
+
+        JSObject* const & operator*() const { return m_node->object; }
+        JSObject* const * operator->() const { return &(operator*()); }
+    
+        ScopeChainIterator& operator++() { m_node = m_node->next; return *this; }
+
+        // postfix ++ intentionally omitted
+
+        bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; }
+        bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
+
+    private:
+        const ScopeChainNode* m_node;
+    };
+
+    inline ScopeChainIterator ScopeChainNode::begin() const
+    {
+        return ScopeChainIterator(this); 
+    }
+
+    inline ScopeChainIterator ScopeChainNode::end() const
+    { 
+        return ScopeChainIterator(0); 
+    }
+
+    class NoScopeChain {};
+
+    class ScopeChain {
+        friend class CTI;
+    public:
+        ScopeChain(NoScopeChain)
+            : m_node(0)
+        {
+        }
+
+        ScopeChain(JSObject* o, JSGlobalData* globalData, JSObject* globalThis)
+            : m_node(new ScopeChainNode(0, o, globalData, globalThis))
+        {
+        }
+
+        ScopeChain(const ScopeChain& c)
+            : m_node(c.m_node->copy())
+        {
+        }
+
+        ScopeChain& operator=(const ScopeChain& c);
+
+        explicit ScopeChain(ScopeChainNode* node)
+            : m_node(node->copy())
+        {
+        }
+
+        ~ScopeChain()
+        {
+            if (m_node)
+                m_node->deref();
+        }
+
+        void swap(ScopeChain&);
+
+        ScopeChainNode* node() const { return m_node; }
+
+        JSObject* top() const { return m_node->object; }
+
+        ScopeChainIterator begin() const { return m_node->begin(); }
+        ScopeChainIterator end() const { return m_node->end(); }
+
+        void push(JSObject* o) { m_node = m_node->push(o); }
+
+        void pop() { m_node = m_node->pop(); }
+        void clear() { m_node->deref(); m_node = 0; }
+        
+        JSGlobalObject* globalObject() const { return m_node->globalObject(); }
+
+        void mark() const;
+
+#ifndef NDEBUG        
+        void print() const { m_node->print(); }
+#endif
+
+    private:
+        ScopeChainNode* m_node;
+    };
+
+    inline void ScopeChain::swap(ScopeChain& o)
+    {
+        ScopeChainNode* tmp = m_node;
+        m_node = o.m_node;
+        o.m_node = tmp;
+    }
+
+    inline ScopeChain& ScopeChain::operator=(const ScopeChain& c)
+    {
+        ScopeChain tmp(c);
+        swap(tmp);
+        return *this;
+    }
+
+} // namespace JSC
+
+#endif // ScopeChain_h
diff --git a/JavaScriptCore/runtime/ScopeChainMark.h b/JavaScriptCore/runtime/ScopeChainMark.h
new file mode 100644
index 0000000..b80b8ef
--- /dev/null
+++ b/JavaScriptCore/runtime/ScopeChainMark.h
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2003, 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.
+ *
+ */
+
+#ifndef ScopeChainMark_h
+#define ScopeChainMark_h
+
+#include "ScopeChain.h"
+
+namespace JSC {
+
+    inline void ScopeChain::mark() const
+    {
+        for (ScopeChainNode* n = m_node; n; n = n->next) {
+            JSObject* o = n->object;
+            if (!o->marked())
+                o->mark();
+        }
+    }
+
+} // namespace JSC
+
+#endif // ScopeChainMark_h
diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp
new file mode 100644
index 0000000..06811b9
--- /dev/null
+++ b/JavaScriptCore/runtime/SmallStrings.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SmallStrings.h"
+
+#include "JSGlobalObject.h"
+#include "JSString.h"
+
+namespace JSC {
+
+class SmallStringsStorage {
+public:
+    SmallStringsStorage();
+    ~SmallStringsStorage();
+
+    UString::Rep* rep(unsigned char character) { return &reps[character]; }
+
+private:
+    UChar characters[0x100];
+    UString::Rep* reps;
+};
+
+SmallStringsStorage::SmallStringsStorage()
+    : reps(static_cast<UString::Rep*>(fastZeroedMalloc(sizeof(UString::Rep) * 0x100)))
+{
+    for (unsigned i = 0; i < 0x100; ++i) {
+        characters[i] = i;
+        reps[i].offset = i;
+        reps[i].len = 1;
+        reps[i].rc = 1;
+        reps[i].baseString = &reps[0];
+    }
+    reps[0].rc = 0x101;
+    reps[0].buf = characters;
+
+    // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
+    reps[0].usedCapacity = 0x101;
+    reps[0].capacity = 0x101;
+}
+
+SmallStringsStorage::~SmallStringsStorage()
+{
+    fastFree(reps);
+}
+
+SmallStrings::SmallStrings()
+    : m_emptyString(0)
+    , m_storage(0)
+{
+    for (unsigned i = 0; i < 0x100; ++i)
+        m_singleCharacterStrings[i] = 0;
+}
+
+SmallStrings::~SmallStrings()
+{
+}
+
+void SmallStrings::mark()
+{
+    if (m_emptyString && !m_emptyString->marked())
+        m_emptyString->mark();
+    for (unsigned i = 0; i < 0x100; ++i) {
+        if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked())
+            m_singleCharacterStrings[i]->mark();
+    }
+}
+    
+void SmallStrings::createEmptyString(JSGlobalData* globalData)
+{
+    ASSERT(!m_emptyString);
+    m_emptyString = new (globalData) JSString(globalData, "", JSString::HasOtherOwner);
+}
+
+void SmallStrings::createSingleCharacterString(JSGlobalData* globalData, unsigned char character)
+{
+    if (!m_storage)
+        m_storage.set(new SmallStringsStorage);
+    ASSERT(!m_singleCharacterStrings[character]);
+    m_singleCharacterStrings[character] = new (globalData) JSString(globalData, m_storage->rep(character), JSString::HasOtherOwner);
+}
+
+UString::Rep* SmallStrings::singleCharacterStringRep(unsigned char character)
+{
+    if (!m_storage)
+        m_storage.set(new SmallStringsStorage);
+    return m_storage->rep(character);
+}
+
+}
diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h
new file mode 100644
index 0000000..7c71208
--- /dev/null
+++ b/JavaScriptCore/runtime/SmallStrings.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SmallStrings_h
+#define SmallStrings_h
+
+#include "ustring.h"
+#include <wtf/OwnPtr.h>
+
+namespace JSC {
+
+    class JSGlobalData;
+    class JSString;
+
+    class SmallStringsStorage;
+
+    class SmallStrings : Noncopyable {
+    public:
+        SmallStrings();
+        ~SmallStrings();
+
+        JSString* emptyString(JSGlobalData* globalData)
+        {
+            if (!m_emptyString)
+                createEmptyString(globalData);
+            return m_emptyString;
+        }
+        JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character)
+        {
+            if (!m_singleCharacterStrings[character])
+                createSingleCharacterString(globalData, character);
+            return m_singleCharacterStrings[character];
+        }
+
+        UString::Rep* singleCharacterStringRep(unsigned char character);
+        
+        void mark();
+        
+    private:
+        void createEmptyString(JSGlobalData*);
+        void createSingleCharacterString(JSGlobalData*, unsigned char);
+
+        JSString* m_emptyString;
+        JSString* m_singleCharacterStrings[0x100];
+        OwnPtr<SmallStringsStorage> m_storage;
+    };
+    
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/StringConstructor.cpp b/JavaScriptCore/runtime/StringConstructor.cpp
new file mode 100644
index 0000000..850310e
--- /dev/null
+++ b/JavaScriptCore/runtime/StringConstructor.cpp
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "StringConstructor.h"
+
+#include "JSGlobalObject.h"
+#include "PrototypeFunction.h"
+#include "StringPrototype.h"
+
+namespace JSC {
+
+static NEVER_INLINE JSValue* stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
+{
+    UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar)));
+    UChar* p = buf;
+    ArgList::const_iterator end = args.end();
+    for (ArgList::const_iterator it = args.begin(); it != end; ++it)
+        *p++ = static_cast<UChar>((*it).jsValue(exec)->toUInt32(exec));
+    return jsString(exec, UString(buf, p - buf, false));
+}
+
+static JSValue* stringFromCharCode(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    if (LIKELY(args.size() == 1))
+        return jsSingleCharacterString(exec, args.at(exec, 0)->toUInt32(exec));
+    return stringFromCharCodeSlowCase(exec, args);
+}
+
+ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
+
+StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure, StringPrototype* stringPrototype)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, stringPrototype->classInfo()->className))
+{
+    // ECMA 15.5.3.1 String.prototype
+    putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
+
+    // ECMA 15.5.3.2 fromCharCode()
+    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
+
+    // no. of arguments for constructor
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
+}
+
+// ECMA 15.5.2
+static JSObject* constructWithStringConstructor(ExecState* exec, JSObject*, const ArgList& args)
+{
+    if (args.isEmpty())
+        return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure());
+    return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(exec, 0)->toString(exec));
+}
+
+ConstructType StringConstructor::getConstructData(ConstructData& constructData)
+{
+    constructData.native.function = constructWithStringConstructor;
+    return ConstructTypeHost;
+}
+
+// ECMA 15.5.1
+static JSValue* callStringConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+{
+    if (args.isEmpty())
+        return jsEmptyString(exec);
+    return jsString(exec, args.at(exec, 0)->toString(exec));
+}
+
+CallType StringConstructor::getCallData(CallData& callData)
+{
+    callData.native.function = callStringConstructor;
+    return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/StringConstructor.h b/JavaScriptCore/runtime/StringConstructor.h
new file mode 100644
index 0000000..3376134
--- /dev/null
+++ b/JavaScriptCore/runtime/StringConstructor.h
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef StringConstructor_h
+#define StringConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+    class StringPrototype;
+
+    class StringConstructor : public InternalFunction {
+    public:
+        StringConstructor(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure, StringPrototype*);
+
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual CallType getCallData(CallData&);
+    };
+
+} // namespace JSC
+
+#endif // StringConstructor_h
diff --git a/JavaScriptCore/runtime/StringObject.cpp b/JavaScriptCore/runtime/StringObject.cpp
new file mode 100644
index 0000000..5959395
--- /dev/null
+++ b/JavaScriptCore/runtime/StringObject.cpp
@@ -0,0 +1,101 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "StringObject.h"
+
+#include "PropertyNameArray.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(StringObject);
+
+const ClassInfo StringObject::info = { "String", 0, 0, 0 };
+
+StringObject::StringObject(ExecState* exec, PassRefPtr<StructureID> structure)
+    : JSWrapperObject(structure)
+{
+    setInternalValue(jsEmptyString(exec));
+}
+
+StringObject::StringObject(PassRefPtr<StructureID> structure, JSString* string)
+    : JSWrapperObject(structure)
+{
+    setInternalValue(string);
+}
+
+StringObject::StringObject(ExecState* exec, PassRefPtr<StructureID> structure, const UString& string)
+    : JSWrapperObject(structure)
+{
+    setInternalValue(jsString(exec, string));
+}
+
+bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
+        return true;
+    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+}
+    
+bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+    if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
+        return true;    
+    return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
+}
+
+void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+{
+    if (propertyName == exec->propertyNames().length)
+        return;
+    JSObject::put(exec, propertyName, value, slot);
+}
+
+bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    if (propertyName == exec->propertyNames().length)
+        return false;
+    return JSObject::deleteProperty(exec, propertyName);
+}
+
+void StringObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+{
+    int size = internalValue()->value().size();
+    for (int i = 0; i < size; ++i)
+        propertyNames.add(Identifier(exec, UString::from(i)));
+    return JSObject::getPropertyNames(exec, propertyNames);
+}
+
+UString StringObject::toString(ExecState*) const
+{
+    return internalValue()->value();
+}
+
+UString StringObject::toThisString(ExecState*) const
+{
+    return internalValue()->value();
+}
+
+JSString* StringObject::toThisJSString(ExecState*)
+{
+    return internalValue();
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/StringObject.h b/JavaScriptCore/runtime/StringObject.h
new file mode 100644
index 0000000..9297fd7
--- /dev/null
+++ b/JavaScriptCore/runtime/StringObject.h
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef StringObject_h
+#define StringObject_h
+
+#include "JSWrapperObject.h"
+#include "JSString.h"
+
+namespace JSC {
+
+    class StringObject : public JSWrapperObject {
+    public:
+        StringObject(ExecState*, PassRefPtr<StructureID>);
+        StringObject(ExecState*, PassRefPtr<StructureID>, const UString&);
+
+        static StringObject* create(ExecState*, JSString*);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+
+        virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+
+        JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+        {
+            return StructureID::create(prototype, TypeInfo(ObjectType));
+        }
+
+    protected:
+        StringObject(PassRefPtr<StructureID>, JSString*);
+
+    private:
+        virtual UString toString(ExecState*) const;
+        virtual UString toThisString(ExecState*) const;
+        virtual JSString* toThisJSString(ExecState*);
+  };
+
+    StringObject* asStringObject(JSValue*);
+
+    inline StringObject* asStringObject(JSValue* value)
+    {
+        ASSERT(asObject(value)->inherits(&StringObject::info));
+        return static_cast<StringObject*>(asObject(value));
+    }
+
+} // namespace JSC
+
+#endif // StringObject_h
diff --git a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
new file mode 100644
index 0000000..d703228
--- /dev/null
+++ b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef StringObjectThatMasqueradesAsUndefined_h
+#define StringObjectThatMasqueradesAsUndefined_h
+
+#include "JSGlobalObject.h"
+#include "StringObject.h"
+#include "ustring.h"
+
+namespace JSC {
+
+    // WebCore uses this to make style.filter undetectable
+    class StringObjectThatMasqueradesAsUndefined : public StringObject {
+    public:
+        static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string)
+        {
+            return new (exec) StringObjectThatMasqueradesAsUndefined(exec,
+                createStructureID(exec->lexicalGlobalObject()->stringPrototype()), string);
+        }
+
+    private:
+        StringObjectThatMasqueradesAsUndefined(ExecState* exec, PassRefPtr<StructureID> structure, const UString& string)
+            : StringObject(exec, structure, string)
+        {
+        }
+
+        static PassRefPtr<StructureID> createStructureID(JSValue* proto) 
+        { 
+            return StructureID::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined)); 
+        }
+
+        virtual bool toBoolean(ExecState*) const { return false; }
+    };
+ 
+} // namespace JSC
+
+#endif // StringObjectThatMasqueradesAsUndefined_h
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
new file mode 100644
index 0000000..0b11c24
--- /dev/null
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -0,0 +1,774 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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 "StringPrototype.h"
+
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "ObjectPrototype.h"
+#include "PropertyNameArray.h"
+#include "RegExpConstructor.h"
+#include "RegExpObject.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/MathExtras.h>
+#include <wtf/unicode/Collator.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(StringPrototype);
+
+static JSValue* stringProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncCharAt(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncMatch(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncReplace(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSearch(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSlice(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSplit(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSubstr(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSubstring(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+static JSValue* stringProtoFuncBig(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSmall(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncBlink(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncBold(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncItalics(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncStrike(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSub(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncSup(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncFontcolor(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncFontsize(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncAnchor(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValue* stringProtoFuncLink(ExecState*, JSObject*, JSValue*, const ArgList&);
+
+}
+
+#include "StringPrototype.lut.h"
+
+namespace JSC {
+
+const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, ExecState::stringTable };
+
+/* Source for StringPrototype.lut.h
+@begin stringTable 26
+    toString              stringProtoFuncToString          DontEnum|Function       0
+    valueOf               stringProtoFuncToString          DontEnum|Function       0
+    charAt                stringProtoFuncCharAt            DontEnum|Function       1
+    charCodeAt            stringProtoFuncCharCodeAt        DontEnum|Function       1
+    concat                stringProtoFuncConcat            DontEnum|Function       1
+    indexOf               stringProtoFuncIndexOf           DontEnum|Function       1
+    lastIndexOf           stringProtoFuncLastIndexOf       DontEnum|Function       1
+    match                 stringProtoFuncMatch             DontEnum|Function       1
+    replace               stringProtoFuncReplace           DontEnum|Function       2
+    search                stringProtoFuncSearch            DontEnum|Function       1
+    slice                 stringProtoFuncSlice             DontEnum|Function       2
+    split                 stringProtoFuncSplit             DontEnum|Function       2
+    substr                stringProtoFuncSubstr            DontEnum|Function       2
+    substring             stringProtoFuncSubstring         DontEnum|Function       2
+    toLowerCase           stringProtoFuncToLowerCase       DontEnum|Function       0
+    toUpperCase           stringProtoFuncToUpperCase       DontEnum|Function       0
+    localeCompare         stringProtoFuncLocaleCompare     DontEnum|Function       1
+
+    # toLocaleLowerCase and toLocaleUpperCase are currently identical to toLowerCase and toUpperCase
+    toLocaleLowerCase     stringProtoFuncToLowerCase       DontEnum|Function       0
+    toLocaleUpperCase     stringProtoFuncToUpperCase       DontEnum|Function       0
+
+    big                   stringProtoFuncBig               DontEnum|Function       0
+    small                 stringProtoFuncSmall             DontEnum|Function       0
+    blink                 stringProtoFuncBlink             DontEnum|Function       0
+    bold                  stringProtoFuncBold              DontEnum|Function       0
+    fixed                 stringProtoFuncFixed             DontEnum|Function       0
+    italics               stringProtoFuncItalics           DontEnum|Function       0
+    strike                stringProtoFuncStrike            DontEnum|Function       0
+    sub                   stringProtoFuncSub               DontEnum|Function       0
+    sup                   stringProtoFuncSup               DontEnum|Function       0
+    fontcolor             stringProtoFuncFontcolor         DontEnum|Function       1
+    fontsize              stringProtoFuncFontsize          DontEnum|Function       1
+    anchor                stringProtoFuncAnchor            DontEnum|Function       1
+    link                  stringProtoFuncLink              DontEnum|Function       1
+@end
+*/
+
+// ECMA 15.5.4
+StringPrototype::StringPrototype(ExecState* exec, PassRefPtr<StructureID> structure)
+    : StringObject(exec, structure)
+{
+    // The constructor will be added later, after StringConstructor has been built
+    putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
+}
+
+bool StringPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
+{
+    return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, slot);
+}
+
+// ------------------------------ Functions --------------------------
+
+static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
+{
+    UString substitutedReplacement;
+    int offset = 0;
+    int i = -1;
+    while ((i = replacement.find('$', i + 1)) != -1) {
+        if (i + 1 == replacement.size())
+            break;
+
+        unsigned short ref = replacement[i + 1];
+        if (ref == '$') {
+            // "$$" -> "$"
+            ++i;
+            substitutedReplacement.append(replacement.data() + offset, i - offset);
+            offset = i + 1;
+            substitutedReplacement.append('$');
+            continue;
+        }
+
+        int backrefStart;
+        int backrefLength;
+        int advance = 0;
+        if (ref == '&') {
+            backrefStart = ovector[0];
+            backrefLength = ovector[1] - backrefStart;
+        } else if (ref == '`') {
+            backrefStart = 0;
+            backrefLength = ovector[0];
+        } else if (ref == '\'') {
+            backrefStart = ovector[1];
+            backrefLength = source.size() - backrefStart;
+        } else if (ref >= '0' && ref <= '9') {
+            // 1- and 2-digit back references are allowed
+            unsigned backrefIndex = ref - '0';
+            if (backrefIndex > reg->numSubpatterns())
+                continue;
+            if (replacement.size() > i + 2) {
+                ref = replacement[i + 2];
+                if (ref >= '0' && ref <= '9') {
+                    backrefIndex = 10 * backrefIndex + ref - '0';
+                    if (backrefIndex > reg->numSubpatterns())
+                        backrefIndex = backrefIndex / 10;   // Fall back to the 1-digit reference
+                    else
+                        advance = 1;
+                }
+            }
+            backrefStart = ovector[2 * backrefIndex];
+            backrefLength = ovector[2 * backrefIndex + 1] - backrefStart;
+        } else
+            continue;
+
+        if (i - offset)
+            substitutedReplacement.append(replacement.data() + offset, i - offset);
+        i += 1 + advance;
+        offset = i + 1;
+        substitutedReplacement.append(source.data() + backrefStart, backrefLength);
+    }
+
+    if (!offset)
+        return replacement;
+
+    if (replacement.size() - offset)
+        substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
+
+    return substitutedReplacement;
+}
+
+static inline int localeCompare(const UString& a, const UString& b)
+{
+    return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.data()), a.size(), reinterpret_cast<const ::UChar*>(b.data()), b.size());
+}
+
+JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    JSString* sourceVal = thisValue->toThisJSString(exec);
+    const UString& source = sourceVal->value();
+
+    JSValue* pattern = args.at(exec, 0);
+
+    JSValue* replacement = args.at(exec, 1);
+    UString replacementString;
+    CallData callData;
+    CallType callType = replacement->getCallData(callData);
+    if (callType == CallTypeNone)
+        replacementString = replacement->toString(exec);
+
+    if (pattern->isObject(&RegExpObject::info)) {
+        RegExp* reg = asRegExpObject(pattern)->regExp();
+        bool global = reg->global();
+
+        RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+
+        int lastIndex = 0;
+        int startPosition = 0;
+
+        Vector<UString::Range, 16> sourceRanges;
+        Vector<UString, 16> replacements;
+
+        // This is either a loop (if global is set) or a one-way (if not).
+        do {
+            int matchIndex;
+            int matchLen;
+            int* ovector;
+            regExpObj->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
+            if (matchIndex < 0)
+                break;
+
+            sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+
+            if (callType != CallTypeNone) {
+                int completeMatchStart = ovector[0];
+                ArgList args;
+
+                for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
+                    int matchStart = ovector[i * 2];
+                    int matchLen = ovector[i * 2 + 1] - matchStart;
+
+                    if (matchStart < 0)
+                        args.append(jsUndefined());
+                    else
+                        args.append(jsSubstring(exec, source, matchStart, matchLen));
+                }
+
+                args.append(jsNumber(exec, completeMatchStart));
+                args.append(sourceVal);
+
+                replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec));
+                if (exec->hadException())
+                    break;
+            } else
+                replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
+
+            lastIndex = matchIndex + matchLen;
+            startPosition = lastIndex;
+
+            // special case of empty match
+            if (matchLen == 0) {
+                startPosition++;
+                if (startPosition > source.size())
+                    break;
+            }
+        } while (global);
+
+        if (lastIndex < source.size())
+            sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+
+        UString result = source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
+
+        if (result == source)
+            return sourceVal;
+
+        return jsString(exec, result);
+    }
+
+    // First arg is a string
+    UString patternString = pattern->toString(exec);
+    int matchPos = source.find(patternString);
+    int matchLen = patternString.size();
+    // Do the replacement
+    if (matchPos == -1)
+        return sourceVal;
+
+    if (callType != CallTypeNone) {
+        ArgList args;
+        args.append(jsSubstring(exec, source, matchPos, matchLen));
+        args.append(jsNumber(exec, matchPos));
+        args.append(sourceVal);
+
+        replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec);
+    }
+
+    return jsString(exec, source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
+}
+
+JSValue* stringProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    // Also used for valueOf.
+
+    if (thisValue->isString())
+        return thisValue;
+
+    if (thisValue->isObject(&StringObject::info))
+        return asStringObject(thisValue)->internalValue();
+
+    return throwError(exec, TypeError);
+}
+
+JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    unsigned len = s.size();
+    JSValue* a0 = args.at(exec, 0);
+    if (JSImmediate::isNumber(a0)) {
+        uint32_t i;
+        if (JSImmediate::getUInt32(a0, i) && i < len)
+            return jsSingleCharacterSubstring(exec, s, i);
+        return jsEmptyString(exec);
+    }
+    double dpos = a0->toInteger(exec);
+    if (dpos >= 0 && dpos < len)
+        return jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos));
+    return jsEmptyString(exec);
+}
+
+JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    unsigned len = s.size();
+    JSValue* a0 = args.at(exec, 0);
+    if (JSImmediate::isNumber(a0)) {
+        uint32_t i;
+        if (JSImmediate::getUInt32(a0, i) && i < len)
+            return jsNumber(exec, s.data()[i]);
+        return jsNaN(exec);
+    }
+    double dpos = a0->toInteger(exec);
+    if (dpos >= 0 && dpos < len)
+        return jsNumber(exec, s[static_cast<int>(dpos)]);
+    return jsNaN(exec);
+}
+
+JSValue* stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+
+    ArgList::const_iterator end = args.end();
+    for (ArgList::const_iterator it = args.begin(); it != end; ++it)
+        s += (*it).jsValue(exec)->toString(exec);
+    return jsString(exec, s);
+}
+
+JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    int len = s.size();
+
+    JSValue* a0 = args.at(exec, 0);
+    JSValue* a1 = args.at(exec, 1);
+    UString u2 = a0->toString(exec);
+    double dpos = a1->toInteger(exec);
+    if (dpos < 0)
+        dpos = 0;
+    else if (dpos > len)
+        dpos = len;
+    return jsNumber(exec, s.find(u2, static_cast<int>(dpos)));
+}
+
+JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    int len = s.size();
+
+    JSValue* a0 = args.at(exec, 0);
+    JSValue* a1 = args.at(exec, 1);
+
+    UString u2 = a0->toString(exec);
+    double dpos = a1->toIntegerPreserveNaN(exec);
+    if (dpos < 0)
+        dpos = 0;
+    else if (!(dpos <= len)) // true for NaN
+        dpos = len;
+    return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
+}
+
+JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+
+    JSValue* a0 = args.at(exec, 0);
+
+    UString u = s;
+    RefPtr<RegExp> reg;
+    RegExpObject* imp = 0;
+    if (a0->isObject(&RegExpObject::info))
+        reg = asRegExpObject(a0)->regExp();
+    else {
+        /*
+         *  ECMA 15.5.4.12 String.prototype.search (regexp)
+         *  If regexp is not an object whose [[Class]] property is "RegExp", it is
+         *  replaced with the result of the expression new RegExp(regexp).
+         */
+        reg = RegExp::create(&exec->globalData(), a0->toString(exec));
+    }
+    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+    int pos;
+    int matchLength;
+    regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
+    if (!(reg->global())) {
+        // case without 'g' flag is handled like RegExp.prototype.exec
+        if (pos < 0)
+            return jsNull();
+        return regExpObj->arrayOfMatches(exec);
+    }
+
+    // return array of matches
+    ArgList list;
+    int lastIndex = 0;
+    while (pos >= 0) {
+        list.append(jsSubstring(exec, u, pos, matchLength));
+        lastIndex = pos;
+        pos += matchLength == 0 ? 1 : matchLength;
+        regExpObj->performMatch(reg.get(), u, pos, pos, matchLength);
+    }
+    if (imp)
+        imp->setLastIndex(lastIndex);
+    if (list.isEmpty()) {
+        // if there are no matches at all, it's important to return
+        // Null instead of an empty array, because this matches
+        // other browsers and because Null is a false value.
+        return jsNull();
+    }
+
+    return constructArray(exec, list);
+}
+
+JSValue* stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+
+    JSValue* a0 = args.at(exec, 0);
+
+    UString u = s;
+    RefPtr<RegExp> reg;
+    if (a0->isObject(&RegExpObject::info))
+        reg = asRegExpObject(a0)->regExp();
+    else { 
+        /*
+         *  ECMA 15.5.4.12 String.prototype.search (regexp)
+         *  If regexp is not an object whose [[Class]] property is "RegExp", it is
+         *  replaced with the result of the expression new RegExp(regexp).
+         */
+        reg = RegExp::create(&exec->globalData(), a0->toString(exec));
+    }
+    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+    int pos;
+    int matchLength;
+    regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
+    return jsNumber(exec, pos);
+}
+
+JSValue* stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    int len = s.size();
+
+    JSValue* a0 = args.at(exec, 0);
+    JSValue* a1 = args.at(exec, 1);
+
+    // The arg processing is very much like ArrayProtoFunc::Slice
+    double start = a0->toInteger(exec);
+    double end = a1->isUndefined() ? len : a1->toInteger(exec);
+    double from = start < 0 ? len + start : start;
+    double to = end < 0 ? len + end : end;
+    if (to > from && to > 0 && from < len) {
+        if (from < 0)
+            from = 0;
+        if (to > len)
+            to = len;
+        return jsSubstring(exec, s, static_cast<unsigned>(from), static_cast<unsigned>(to) - static_cast<unsigned>(from));
+    }
+
+    return jsEmptyString(exec);
+}
+
+JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+
+    JSValue* a0 = args.at(exec, 0);
+    JSValue* a1 = args.at(exec, 1);
+
+    JSArray* result = constructEmptyArray(exec);
+    unsigned i = 0;
+    int p0 = 0;
+    unsigned limit = a1->isUndefined() ? 0xFFFFFFFFU : a1->toUInt32(exec);
+    if (a0->isObject(&RegExpObject::info)) {
+        RegExp* reg = asRegExpObject(a0)->regExp();
+        if (s.isEmpty() && reg->match(s, 0) >= 0) {
+            // empty string matched by regexp -> empty array
+            return result;
+        }
+        int pos = 0;
+        while (i != limit && pos < s.size()) {
+            OwnArrayPtr<int> ovector;
+            int mpos = reg->match(s, pos, &ovector);
+            if (mpos < 0)
+                break;
+            int mlen = ovector[1] - ovector[0];
+            pos = mpos + (mlen == 0 ? 1 : mlen);
+            if (mpos != p0 || mlen) {
+                result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0));
+                p0 = mpos + mlen;
+            }
+            for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) {
+                int spos = ovector[si * 2];
+                if (spos < 0)
+                    result->put(exec, i++, jsUndefined());
+                else
+                    result->put(exec, i++, jsSubstring(exec, s, spos, ovector[si * 2 + 1] - spos));
+            }
+        }
+    } else {
+        UString u2 = a0->toString(exec);
+        if (u2.isEmpty()) {
+            if (s.isEmpty()) {
+                // empty separator matches empty string -> empty array
+                return result;
+            }
+            while (i != limit && p0 < s.size() - 1)
+                result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++));
+        } else {
+            int pos;
+            while (i != limit && (pos = s.find(u2, p0)) >= 0) {
+                result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0));
+                p0 = pos + u2.size();
+            }
+        }
+    }
+
+    // add remaining string
+    if (i != limit)
+        result->put(exec, i++, jsSubstring(exec, s, p0, s.size() - p0));
+
+    return result;
+}
+
+JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    int len = s.size();
+
+    JSValue* a0 = args.at(exec, 0);
+    JSValue* a1 = args.at(exec, 1);
+
+    double start = a0->toInteger(exec);
+    double length = a1->isUndefined() ? len : a1->toInteger(exec);
+    if (start >= len || length <= 0)
+        return jsEmptyString(exec);
+    if (start < 0) {
+        start += len;
+        if (start < 0)
+            start = 0;
+    }
+    if (start + length > len)
+        length = len - start;
+    return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(length));
+}
+
+JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    int len = s.size();
+
+    JSValue* a0 = args.at(exec, 0);
+    JSValue* a1 = args.at(exec, 1);
+
+    double start = a0->toNumber(exec);
+    double end = a1->toNumber(exec);
+    if (isnan(start))
+        start = 0;
+    if (isnan(end))
+        end = 0;
+    if (start < 0)
+        start = 0;
+    if (end < 0)
+        end = 0;
+    if (start > len)
+        start = len;
+    if (end > len)
+        end = len;
+    if (a1->isUndefined())
+        end = len;
+    if (start > end) {
+        double temp = end;
+        end = start;
+        start = temp;
+    }
+    return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(end) - static_cast<unsigned>(start));
+}
+
+JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    JSString* sVal = thisValue->toThisJSString(exec);
+    const UString& s = sVal->value();
+
+    int sSize = s.size();
+    if (!sSize)
+        return sVal;
+
+    const UChar* sData = s.data();
+    Vector<UChar> buffer(sSize);
+
+    UChar ored = 0;
+    for (int i = 0; i < sSize; i++) {
+        UChar c = sData[i];
+        ored |= c;
+        buffer[i] = toASCIILower(c);
+    }
+    if (!(ored & ~0x7f))
+        return jsString(exec, UString(buffer.releaseBuffer(), sSize, false));
+
+    bool error;
+    int length = Unicode::toLower(buffer.data(), sSize, sData, sSize, &error);
+    if (error) {
+        buffer.resize(length);
+        length = Unicode::toLower(buffer.data(), length, sData, sSize, &error);
+        if (error)
+            return sVal;
+    }
+    if (length == sSize && memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
+        return sVal;
+    return jsString(exec, UString(buffer.releaseBuffer(), length, false));
+}
+
+JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    JSString* sVal = thisValue->toThisJSString(exec);
+    const UString& s = sVal->value();
+
+    int sSize = s.size();
+    if (!sSize)
+        return sVal;
+
+    const UChar* sData = s.data();
+    Vector<UChar> buffer(sSize);
+
+    UChar ored = 0;
+    for (int i = 0; i < sSize; i++) {
+        UChar c = sData[i];
+        ored |= c;
+        buffer[i] = toASCIIUpper(c);
+    }
+    if (!(ored & ~0x7f))
+        return jsString(exec, UString(buffer.releaseBuffer(), sSize, false));
+
+    bool error;
+    int length = Unicode::toUpper(buffer.data(), sSize, sData, sSize, &error);
+    if (error) {
+        buffer.resize(length);
+        length = Unicode::toUpper(buffer.data(), length, sData, sSize, &error);
+        if (error)
+            return sVal;
+    }
+    if (length == sSize && memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
+        return sVal;
+    return jsString(exec, UString(buffer.releaseBuffer(), length, false));
+}
+
+JSValue* stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    if (args.size() < 1)
+      return jsNumber(exec, 0);
+
+    UString s = thisValue->toThisString(exec);
+    JSValue* a0 = args.at(exec, 0);
+    return jsNumber(exec, localeCompare(s, a0->toString(exec)));
+}
+
+JSValue* stringProtoFuncBig(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<big>" + s + "</big>");
+}
+
+JSValue* stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<small>" + s + "</small>");
+}
+
+JSValue* stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<blink>" + s + "</blink>");
+}
+
+JSValue* stringProtoFuncBold(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<b>" + s + "</b>");
+}
+
+JSValue* stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<tt>" + s + "</tt>");
+}
+
+JSValue* stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<i>" + s + "</i>");
+}
+
+JSValue* stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<strike>" + s + "</strike>");
+}
+
+JSValue* stringProtoFuncSub(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<sub>" + s + "</sub>");
+}
+
+JSValue* stringProtoFuncSup(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+{
+    UString s = thisValue->toThisString(exec);
+    return jsString(exec, "<sup>" + s + "</sup>");
+}
+
+JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    JSValue* a0 = args.at(exec, 0);
+    return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
+}
+
+JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    JSValue* a0 = args.at(exec, 0);
+    return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
+}
+
+JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    JSValue* a0 = args.at(exec, 0);
+    return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
+}
+
+JSValue* stringProtoFuncLink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+{
+    UString s = thisValue->toThisString(exec);
+    JSValue* a0 = args.at(exec, 0);
+    return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/StringPrototype.h b/JavaScriptCore/runtime/StringPrototype.h
new file mode 100644
index 0000000..b127885
--- /dev/null
+++ b/JavaScriptCore/runtime/StringPrototype.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU 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
+ *
+ */
+
+#ifndef StringPrototype_h
+#define StringPrototype_h
+
+#include "StringObject.h"
+
+namespace JSC {
+
+    class ObjectPrototype;
+
+    class StringPrototype : public StringObject {
+    public:
+        StringPrototype(ExecState*, PassRefPtr<StructureID>);
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+    };
+
+} // namespace JSC
+
+#endif // StringPrototype_h
diff --git a/JavaScriptCore/runtime/StructureID.cpp b/JavaScriptCore/runtime/StructureID.cpp
new file mode 100644
index 0000000..8333595
--- /dev/null
+++ b/JavaScriptCore/runtime/StructureID.cpp
@@ -0,0 +1,902 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "StructureID.h"
+
+#include "JSObject.h"
+#include "PropertyNameArray.h"
+#include "StructureIDChain.h"
+#include "identifier.h"
+#include "lookup.h"
+#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/RefPtr.h>
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+#include <wtf/Threading.h>
+#endif
+
+#define DUMP_STRUCTURE_ID_STATISTICS 0
+
+#ifndef NDEBUG
+#define DO_PROPERTYMAP_CONSTENCY_CHECK 0
+#else
+#define DO_PROPERTYMAP_CONSTENCY_CHECK 0
+#endif
+
+using namespace std;
+using WTF::doubleHash;
+
+namespace JSC {
+
+// Choose a number for the following so that most property maps are smaller,
+// but it's not going to blow out the stack to allocate this number of pointers.
+static const int smallMapThreshold = 1024;
+
+// The point at which the function call overhead of the qsort implementation
+// becomes small compared to the inefficiency of insertion sort.
+static const unsigned tinyMapThreshold = 20;
+
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter structureIDCounter("StructureID");
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+static Mutex ignoreSetMutex;
+#endif
+
+static bool shouldIgnoreLeaks;
+static HashSet<StructureID*> ignoreSet;
+#endif
+
+#if DUMP_STRUCTURE_ID_STATISTICS
+static HashSet<StructureID*> liveStructureIDSet;
+#endif
+
+void StructureID::dumpStatistics()
+{
+#if DUMP_STRUCTURE_ID_STATISTICS
+    unsigned numberLeaf = 0;
+    unsigned numberUsingSingleSlot = 0;
+    unsigned numberSingletons = 0;
+    unsigned totalPropertyMapsSize = 0;
+
+    HashSet<StructureID*>::const_iterator end = liveStructureIDSet.end();
+    for (HashSet<StructureID*>::const_iterator it = liveStructureIDSet.begin(); it != end; ++it) {
+        StructureID* structureID = *it;
+        if (structureID->m_usingSingleTransitionSlot) {
+            if (!structureID->m_transitions.singleTransition)
+                ++numberLeaf;
+            else
+                ++numberUsingSingleSlot;
+
+           if (!structureID->m_previous && !structureID->m_transitions.singleTransition)
+                ++numberSingletons;
+        }
+
+        if (structureID->m_propertyTable)
+            totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structureID->m_propertyTable->size);
+    }
+
+    printf("Number of live StructureIDs: %d\n", liveStructureIDSet.size());
+    printf("Number of StructureIDs using the single item optimization for transition map: %d\n", numberUsingSingleSlot);
+    printf("Number of StructureIDs that are leaf nodes: %d\n", numberLeaf);
+    printf("Number of StructureIDs that singletons: %d\n", numberSingletons);
+
+    printf("Size of a single StructureIDs: %d\n", static_cast<unsigned>(sizeof(StructureID)));
+    printf("Size of sum of all property maps: %d\n", totalPropertyMapsSize);
+    printf("Size of average of all property maps: %f\n", static_cast<double>(totalPropertyMapsSize) / static_cast<double>(liveStructureIDSet.size()));
+#else
+    printf("Dumping StructureID statistics is not enabled.\n");
+#endif
+}
+
+StructureID::StructureID(JSValue* prototype, const TypeInfo& typeInfo)
+    : m_typeInfo(typeInfo)
+    , m_prototype(prototype)
+    , m_cachedPrototypeChain(0)
+    , m_previous(0)
+    , m_nameInPrevious(0)
+    , m_transitionCount(0)
+    , m_propertyTable(0)
+    , m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
+    , m_cachedTransistionOffset(WTF::notFound)
+    , m_isDictionary(false)
+    , m_hasGetterSetterProperties(false)
+    , m_usingSingleTransitionSlot(true)
+    , m_attributesInPrevious(0)
+{
+    ASSERT(m_prototype);
+    ASSERT(m_prototype->isObject() || m_prototype->isNull());
+
+    m_transitions.singleTransition = 0;
+
+#ifndef NDEBUG
+#if ENABLE(JSC_MULTIPLE_THREADS)
+    MutexLocker protect(ignoreSetMutex);
+#endif
+    if (shouldIgnoreLeaks)
+        ignoreSet.add(this);
+    else
+        structureIDCounter.increment();
+#endif
+
+#if DUMP_STRUCTURE_ID_STATISTICS
+    liveStructureIDSet.add(this);
+#endif
+}
+
+StructureID::~StructureID()
+{
+    if (m_previous) {
+        if (m_previous->m_usingSingleTransitionSlot) {
+            m_previous->m_transitions.singleTransition = 0;
+        } else {
+            ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious, m_attributesInPrevious)));
+            m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious, m_attributesInPrevious));
+        }
+    }
+
+    if (m_cachedPropertyNameArrayData)
+        m_cachedPropertyNameArrayData->setCachedStructureID(0);
+
+    if (!m_usingSingleTransitionSlot)
+        delete m_transitions.table;
+
+    if (m_propertyTable) {
+        unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+        for (unsigned i = 1; i <= entryCount; i++) {
+            if (UString::Rep* key = m_propertyTable->entries()[i].key)
+                key->deref();
+        }
+        fastFree(m_propertyTable);
+    }
+
+#ifndef NDEBUG
+#if ENABLE(JSC_MULTIPLE_THREADS)
+    MutexLocker protect(ignoreSetMutex);
+#endif
+    HashSet<StructureID*>::iterator it = ignoreSet.find(this);
+    if (it != ignoreSet.end())
+        ignoreSet.remove(it);
+    else
+        structureIDCounter.decrement();
+#endif
+
+#if DUMP_STRUCTURE_ID_STATISTICS
+    liveStructureIDSet.remove(this);
+#endif
+}
+
+void StructureID::startIgnoringLeaks()
+{
+#ifndef NDEBUG
+    shouldIgnoreLeaks = true;
+#endif
+}
+
+void StructureID::stopIgnoringLeaks()
+{
+#ifndef NDEBUG
+    shouldIgnoreLeaks = false;
+#endif
+}
+
+void StructureID::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
+{
+    bool shouldCache = propertyNames.cacheable() && !(propertyNames.size() || m_isDictionary);
+
+    if (shouldCache) {
+        if (m_cachedPropertyNameArrayData) {
+            if (structureIDChainsAreEqual(m_cachedPropertyNameArrayData->cachedPrototypeChain(), cachedPrototypeChain())) {
+                propertyNames.setData(m_cachedPropertyNameArrayData);
+                return;
+            }
+        }
+        propertyNames.setCacheable(false);
+    }
+
+    getEnumerablePropertyNamesInternal(propertyNames);
+
+    // Add properties from the static hashtables of properties
+    for (const ClassInfo* info = baseObject->classInfo(); info; info = info->parentClass) {
+        const HashTable* table = info->propHashTable(exec);
+        if (!table)
+            continue;
+        table->initializeIfNeeded(exec);
+        ASSERT(table->table);
+        int hashSizeMask = table->hashSizeMask;
+        const HashEntry* entry = table->table;
+        for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
+            if (entry->key() && !(entry->attributes() & DontEnum))
+                propertyNames.add(entry->key());
+        }
+    }
+
+    if (m_prototype->isObject())
+        asObject(m_prototype)->getPropertyNames(exec, propertyNames);
+
+    if (shouldCache) {
+        if (m_cachedPropertyNameArrayData)
+            m_cachedPropertyNameArrayData->setCachedStructureID(0);
+
+        m_cachedPropertyNameArrayData = propertyNames.data();
+
+        StructureIDChain* chain = cachedPrototypeChain();
+        if (!chain)
+            chain = createCachedPrototypeChain();
+        m_cachedPropertyNameArrayData->setCachedPrototypeChain(chain);
+        m_cachedPropertyNameArrayData->setCachedStructureID(this);
+    }
+}
+
+void StructureID::clearEnumerationCache()
+{
+    if (m_cachedPropertyNameArrayData)
+        m_cachedPropertyNameArrayData->setCachedStructureID(0);
+    m_cachedPropertyNameArrayData.clear();
+}
+
+void StructureID::growPropertyStorageCapacity()
+{
+    if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
+        m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity;
+    else
+        m_propertyStorageCapacity *= 2;
+}
+
+PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, unsigned attributes, size_t& offset)
+{
+    ASSERT(!structureID->m_isDictionary);
+    ASSERT(structureID->typeInfo().type() == ObjectType);
+
+    if (structureID->m_usingSingleTransitionSlot) {
+        StructureID* existingTransition = structureID->m_transitions.singleTransition;
+        if (existingTransition && existingTransition->m_nameInPrevious == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) {
+            offset = structureID->m_transitions.singleTransition->cachedTransistionOffset();
+            ASSERT(offset != WTF::notFound);
+            return existingTransition;
+        }
+    } else {
+        if (StructureID* existingTransition = structureID->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) {
+            offset = existingTransition->cachedTransistionOffset();
+            ASSERT(offset != WTF::notFound);
+            return existingTransition;
+        }        
+    }
+
+    if (structureID->m_transitionCount > s_maxTransitionLength) {
+        RefPtr<StructureID> transition = toDictionaryTransition(structureID);
+        offset = transition->put(propertyName, attributes);
+        if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
+            transition->growPropertyStorageCapacity();
+        return transition.release();
+    }
+
+    RefPtr<StructureID> transition = create(structureID->m_prototype, structureID->typeInfo());
+    transition->m_cachedPrototypeChain = structureID->m_cachedPrototypeChain;
+    transition->m_previous = structureID;
+    transition->m_nameInPrevious = propertyName.ustring().rep();
+    transition->m_attributesInPrevious = attributes;
+    transition->m_transitionCount = structureID->m_transitionCount + 1;
+    transition->m_propertyTable = structureID->copyPropertyTable();
+    transition->m_deletedOffsets = structureID->m_deletedOffsets; 
+    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
+    transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+
+    offset = transition->put(propertyName, attributes);
+    if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
+        transition->growPropertyStorageCapacity();
+
+    transition->setCachedTransistionOffset(offset);
+
+    if (structureID->m_usingSingleTransitionSlot) {
+        if (!structureID->m_transitions.singleTransition) {
+            structureID->m_transitions.singleTransition = transition.get();
+            return transition.release();
+        }
+
+        StructureID* existingTransition = structureID->m_transitions.singleTransition;
+        structureID->m_usingSingleTransitionSlot = false;
+        StructureIDTransitionTable* transitionTable = new StructureIDTransitionTable;
+        structureID->m_transitions.table = transitionTable;
+        transitionTable->add(make_pair(existingTransition->m_nameInPrevious, existingTransition->m_attributesInPrevious), existingTransition);
+    }
+    structureID->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
+    return transition.release();
+}
+
+PassRefPtr<StructureID> StructureID::removePropertyTransition(StructureID* structureID, const Identifier& propertyName, size_t& offset)
+{
+    ASSERT(!structureID->m_isDictionary);
+
+    RefPtr<StructureID> transition = create(structureID->m_prototype, structureID->typeInfo());
+    transition->m_isDictionary = true;
+    transition->m_propertyTable = structureID->copyPropertyTable();
+    transition->m_deletedOffsets = structureID->m_deletedOffsets;
+    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
+    transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+
+    offset = transition->remove(propertyName);
+
+    return transition.release();
+}
+
+PassRefPtr<StructureID> StructureID::toDictionaryTransition(StructureID* structureID)
+{
+    ASSERT(!structureID->m_isDictionary);
+
+    RefPtr<StructureID> transition = create(structureID->m_prototype, structureID->typeInfo());
+    transition->m_isDictionary = true;
+    transition->m_propertyTable = structureID->copyPropertyTable();
+    transition->m_deletedOffsets = structureID->m_deletedOffsets;
+    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
+    transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+    return transition.release();
+}
+
+PassRefPtr<StructureID> StructureID::fromDictionaryTransition(StructureID* structureID)
+{
+    ASSERT(structureID->m_isDictionary);
+
+    // Since dictionary StructureIDs are not shared, and no opcodes specialize
+    // for them, we don't need to allocate a new StructureID when transitioning
+    // to non-dictionary status.
+    structureID->m_isDictionary = false;
+    return structureID;
+}
+
+PassRefPtr<StructureID> StructureID::changePrototypeTransition(StructureID* structureID, JSValue* prototype)
+{
+    RefPtr<StructureID> transition = create(prototype, structureID->typeInfo());
+    transition->m_transitionCount = structureID->m_transitionCount + 1;
+    transition->m_propertyTable = structureID->copyPropertyTable();
+    transition->m_deletedOffsets = structureID->m_deletedOffsets;
+    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
+    transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+    return transition.release();
+}
+
+PassRefPtr<StructureID> StructureID::getterSetterTransition(StructureID* structureID)
+{
+    RefPtr<StructureID> transition = create(structureID->storedPrototype(), structureID->typeInfo());
+    transition->m_transitionCount = structureID->m_transitionCount + 1;
+    transition->m_propertyTable = structureID->copyPropertyTable();
+    transition->m_deletedOffsets = structureID->m_deletedOffsets;
+    transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
+    transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
+    return transition.release();
+}
+
+size_t StructureID::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
+{
+    size_t offset = put(propertyName, attributes);
+    if (propertyStorageSize() > propertyStorageCapacity())
+        growPropertyStorageCapacity();
+    clearEnumerationCache();
+    return offset;
+}
+
+size_t StructureID::removePropertyWithoutTransition(const Identifier& propertyName)
+{
+    size_t offset = remove(propertyName);
+    clearEnumerationCache();
+    return offset;
+}
+
+StructureIDChain* StructureID::createCachedPrototypeChain()
+{
+    ASSERT(typeInfo().type() == ObjectType);
+    ASSERT(!m_cachedPrototypeChain);
+
+    JSValue* prototype = storedPrototype();
+    if (JSImmediate::isImmediate(prototype))
+        return 0;
+
+    RefPtr<StructureIDChain> chain = StructureIDChain::create(asObject(prototype)->structureID());
+    setCachedPrototypeChain(chain.release());
+    return cachedPrototypeChain();
+}
+
+#if DUMP_PROPERTYMAP_STATS
+
+static int numProbes;
+static int numCollisions;
+static int numRehashes;
+static int numRemoves;
+
+struct PropertyMapStatisticsExitLogger {
+    ~PropertyMapStatisticsExitLogger();
+};
+
+static PropertyMapStatisticsExitLogger logger;
+
+PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger()
+{
+    printf("\nJSC::PropertyMap statistics\n\n");
+    printf("%d probes\n", numProbes);
+    printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes);
+    printf("%d rehashes\n", numRehashes);
+    printf("%d removes\n", numRemoves);
+}
+
+#endif
+
+static const unsigned deletedSentinelIndex = 1;
+
+#if !DO_PROPERTYMAP_CONSTENCY_CHECK
+
+inline void StructureID::checkConsistency()
+{
+}   
+
+#endif
+
+PropertyMapHashTable* StructureID::copyPropertyTable()
+{
+    if (!m_propertyTable)
+        return 0;
+
+    size_t tableSize = PropertyMapHashTable::allocationSize(m_propertyTable->size);
+    PropertyMapHashTable* newTable = static_cast<PropertyMapHashTable*>(fastMalloc(tableSize));
+    memcpy(newTable, m_propertyTable, tableSize);
+
+    unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+    for (unsigned i = 1; i <= entryCount; ++i) {
+        if (UString::Rep* key = newTable->entries()[i].key)
+            key->ref();
+    }
+
+    return newTable;
+}
+
+size_t StructureID::get(const Identifier& propertyName, unsigned& attributes) const
+{
+    ASSERT(!propertyName.isNull());
+
+    if (!m_propertyTable)
+        return WTF::notFound;
+
+    UString::Rep* rep = propertyName._ustring.rep();
+
+    unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+#endif
+
+    unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+    if (entryIndex == emptyEntryIndex)
+        return WTF::notFound;
+
+    if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+        attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
+        return m_propertyTable->entries()[entryIndex - 1].offset;
+    }
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numCollisions;
+#endif
+
+    unsigned k = 1 | doubleHash(rep->computedHash());
+
+    while (1) {
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+
+        entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            return WTF::notFound;
+
+        if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+            attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
+            return m_propertyTable->entries()[entryIndex - 1].offset;
+        }
+    }
+}
+
+size_t StructureID::put(const Identifier& propertyName, unsigned attributes)
+{
+    ASSERT(!propertyName.isNull());
+    ASSERT(get(propertyName) == WTF::notFound);
+
+    checkConsistency();
+
+    UString::Rep* rep = propertyName._ustring.rep();
+
+    if (!m_propertyTable)
+        createPropertyMapHashTable();
+
+    // FIXME: Consider a fast case for tables with no deleted sentinels.
+
+    unsigned i = rep->computedHash();
+    unsigned k = 0;
+    bool foundDeletedElement = false;
+    unsigned deletedElementIndex = 0; // initialize to make the compiler happy
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+#endif
+
+    while (1) {
+        unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            break;
+
+        if (entryIndex == deletedSentinelIndex) {
+            // If we find a deleted-element sentinel, remember it for use later.
+            if (!foundDeletedElement) {
+                foundDeletedElement = true;
+                deletedElementIndex = i;
+            }
+        }
+
+        if (k == 0) {
+            k = 1 | doubleHash(rep->computedHash());
+#if DUMP_PROPERTYMAP_STATS
+            ++numCollisions;
+#endif
+        }
+
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+    }
+
+    // Figure out which entry to use.
+    unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2;
+    if (foundDeletedElement) {
+        i = deletedElementIndex;
+        --m_propertyTable->deletedSentinelCount;
+
+        // Since we're not making the table bigger, we can't use the entry one past
+        // the end that we were planning on using, so search backwards for the empty
+        // slot that we can use. We know it will be there because we did at least one
+        // deletion in the past that left an entry empty.
+        while (m_propertyTable->entries()[--entryIndex - 1].key) { }
+    }
+
+    // Create a new hash table entry.
+    m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex;
+
+    // Create a new hash table entry.
+    rep->ref();
+    m_propertyTable->entries()[entryIndex - 1].key = rep;
+    m_propertyTable->entries()[entryIndex - 1].attributes = attributes;
+    m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
+
+    unsigned newOffset;
+    if (!m_deletedOffsets.isEmpty()) {
+        newOffset = m_deletedOffsets.last();
+        m_deletedOffsets.removeLast();
+    } else
+        newOffset = m_propertyTable->keyCount;
+    m_propertyTable->entries()[entryIndex - 1].offset = newOffset;
+
+    ++m_propertyTable->keyCount;
+
+    if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size)
+        expandPropertyMapHashTable();
+
+    checkConsistency();
+    return newOffset;
+}
+
+size_t StructureID::remove(const Identifier& propertyName)
+{
+    ASSERT(!propertyName.isNull());
+
+    checkConsistency();
+
+    UString::Rep* rep = propertyName._ustring.rep();
+
+    if (!m_propertyTable)
+        return WTF::notFound;
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+    ++numRemoves;
+#endif
+
+    // Find the thing to remove.
+    unsigned i = rep->computedHash();
+    unsigned k = 0;
+    unsigned entryIndex;
+    UString::Rep* key = 0;
+    while (1) {
+        entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            return WTF::notFound;
+
+        key = m_propertyTable->entries()[entryIndex - 1].key;
+        if (rep == key)
+            break;
+
+        if (k == 0) {
+            k = 1 | doubleHash(rep->computedHash());
+#if DUMP_PROPERTYMAP_STATS
+            ++numCollisions;
+#endif
+        }
+
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+    }
+
+    // Replace this one element with the deleted sentinel. Also clear out
+    // the entry so we can iterate all the entries as needed.
+    m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex;
+
+    size_t offset = m_propertyTable->entries()[entryIndex - 1].offset;
+
+    key->deref();
+    m_propertyTable->entries()[entryIndex - 1].key = 0;
+    m_propertyTable->entries()[entryIndex - 1].attributes = 0;
+    m_propertyTable->entries()[entryIndex - 1].offset = 0;
+    m_deletedOffsets.append(offset);
+
+    ASSERT(m_propertyTable->keyCount >= 1);
+    --m_propertyTable->keyCount;
+    ++m_propertyTable->deletedSentinelCount;
+
+    if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size)
+        rehashPropertyMapHashTable();
+
+    checkConsistency();
+    return offset;
+}
+
+void StructureID::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
+{
+    ASSERT(m_propertyTable);
+
+    unsigned i = entry.key->computedHash();
+    unsigned k = 0;
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+#endif
+
+    while (1) {
+        unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            break;
+
+        if (k == 0) {
+            k = 1 | doubleHash(entry.key->computedHash());
+#if DUMP_PROPERTYMAP_STATS
+            ++numCollisions;
+#endif
+        }
+
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+    }
+
+    unsigned entryIndex = m_propertyTable->keyCount + 2;
+    m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex;
+    m_propertyTable->entries()[entryIndex - 1] = entry;
+
+    ++m_propertyTable->keyCount;
+}
+
+void StructureID::expandPropertyMapHashTable()
+{
+    ASSERT(m_propertyTable);
+    rehashPropertyMapHashTable(m_propertyTable->size * 2);
+}
+
+void StructureID::createPropertyMapHashTable()
+{
+    const unsigned newTableSize = 16;
+
+    ASSERT(!m_propertyTable);
+
+    checkConsistency();
+
+    m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize)));
+    m_propertyTable->size = newTableSize;
+    m_propertyTable->sizeMask = newTableSize - 1;
+
+    checkConsistency();
+}
+
+void StructureID::rehashPropertyMapHashTable()
+{
+    ASSERT(m_propertyTable);
+    ASSERT(m_propertyTable->size);
+    rehashPropertyMapHashTable(m_propertyTable->size);
+}
+
+void StructureID::rehashPropertyMapHashTable(unsigned newTableSize)
+{
+    ASSERT(m_propertyTable);
+
+    checkConsistency();
+
+    PropertyMapHashTable* oldTable = m_propertyTable;
+
+    m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize)));
+    m_propertyTable->size = newTableSize;
+    m_propertyTable->sizeMask = newTableSize - 1;
+
+    unsigned lastIndexUsed = 0;
+    unsigned entryCount = oldTable->keyCount + oldTable->deletedSentinelCount;
+    for (unsigned i = 1; i <= entryCount; ++i) {
+        if (oldTable->entries()[i].key) {
+            lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed);
+            insertIntoPropertyMapHashTable(oldTable->entries()[i]);
+        }
+    }
+    m_propertyTable->lastIndexUsed = lastIndexUsed;
+
+    fastFree(oldTable);
+
+    checkConsistency();
+}
+
+static int comparePropertyMapEntryIndices(const void* a, const void* b)
+{
+    unsigned ia = static_cast<PropertyMapEntry* const*>(a)[0]->index;
+    unsigned ib = static_cast<PropertyMapEntry* const*>(b)[0]->index;
+    if (ia < ib)
+        return -1;
+    if (ia > ib)
+        return +1;
+    return 0;
+}
+
+void StructureID::getEnumerablePropertyNamesInternal(PropertyNameArray& propertyNames) const
+{
+    if (!m_propertyTable)
+        return;
+
+    if (m_propertyTable->keyCount < tinyMapThreshold) {
+        PropertyMapEntry* a[tinyMapThreshold];
+        int i = 0;
+        unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+        for (unsigned k = 1; k <= entryCount; k++) {
+            if (m_propertyTable->entries()[k].key && !(m_propertyTable->entries()[k].attributes & DontEnum)) {
+                PropertyMapEntry* value = &m_propertyTable->entries()[k];
+                int j;
+                for (j = i - 1; j >= 0 && a[j]->index > value->index; --j)
+                    a[j + 1] = a[j];
+                a[j + 1] = value;
+                ++i;
+            }
+        }
+        if (!propertyNames.size()) {
+            for (int k = 0; k < i; ++k)
+                propertyNames.addKnownUnique(a[k]->key);
+        } else {
+            for (int k = 0; k < i; ++k)
+                propertyNames.add(a[k]->key);
+        }
+
+        return;
+    }
+
+    // Allocate a buffer to use to sort the keys.
+    Vector<PropertyMapEntry*, smallMapThreshold> sortedEnumerables(m_propertyTable->keyCount);
+
+    // Get pointers to the enumerable entries in the buffer.
+    PropertyMapEntry** p = sortedEnumerables.data();
+    unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+    for (unsigned i = 1; i <= entryCount; i++) {
+        if (m_propertyTable->entries()[i].key && !(m_propertyTable->entries()[i].attributes & DontEnum))
+            *p++ = &m_propertyTable->entries()[i];
+    }
+
+    size_t enumerableCount = p - sortedEnumerables.data();
+    // Sort the entries by index.
+    qsort(sortedEnumerables.data(), enumerableCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices);
+    sortedEnumerables.resize(enumerableCount);
+
+    // Put the keys of the sorted entries into the list.
+    if (!propertyNames.size()) {
+        for (size_t i = 0; i < sortedEnumerables.size(); ++i)
+            propertyNames.addKnownUnique(sortedEnumerables[i]->key);
+    } else {
+        for (size_t i = 0; i < sortedEnumerables.size(); ++i)
+            propertyNames.add(sortedEnumerables[i]->key);
+    }
+}
+
+#if DO_PROPERTYMAP_CONSTENCY_CHECK
+
+void StructureID::checkConsistency()
+{
+    if (!m_propertyTable)
+        return;
+
+    ASSERT(m_propertyTable->size >= 16);
+    ASSERT(m_propertyTable->sizeMask);
+    ASSERT(m_propertyTable->size == m_propertyTable->sizeMask + 1);
+    ASSERT(!(m_propertyTable->size & m_propertyTable->sizeMask));
+
+    ASSERT(m_propertyTable->keyCount <= m_propertyTable->size / 2);
+    ASSERT(m_propertyTable->deletedSentinelCount <= m_propertyTable->size / 4);
+
+    ASSERT(m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount <= m_propertyTable->size / 2);
+
+    unsigned indexCount = 0;
+    unsigned deletedIndexCount = 0;
+    for (unsigned a = 0; a != m_propertyTable->size; ++a) {
+        unsigned entryIndex = m_propertyTable->entryIndices[a];
+        if (entryIndex == emptyEntryIndex)
+            continue;
+        if (entryIndex == deletedSentinelIndex) {
+            ++deletedIndexCount;
+            continue;
+        }
+        ASSERT(entryIndex > deletedSentinelIndex);
+        ASSERT(entryIndex - 1 <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount);
+        ++indexCount;
+
+        for (unsigned b = a + 1; b != m_propertyTable->size; ++b)
+            ASSERT(m_propertyTable->entryIndices[b] != entryIndex);
+    }
+    ASSERT(indexCount == m_propertyTable->keyCount);
+    ASSERT(deletedIndexCount == m_propertyTable->deletedSentinelCount);
+
+    ASSERT(m_propertyTable->entries()[0].key == 0);
+
+    unsigned nonEmptyEntryCount = 0;
+    for (unsigned c = 1; c <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; ++c) {
+        UString::Rep* rep = m_propertyTable->entries()[c].key;
+        if (!rep)
+            continue;
+        ++nonEmptyEntryCount;
+        unsigned i = rep->computedHash();
+        unsigned k = 0;
+        unsigned entryIndex;
+        while (1) {
+            entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+            ASSERT(entryIndex != emptyEntryIndex);
+            if (rep == m_propertyTable->entries()[entryIndex - 1].key)
+                break;
+            if (k == 0)
+                k = 1 | doubleHash(rep->computedHash());
+            i += k;
+        }
+        ASSERT(entryIndex == c + 1);
+    }
+
+    ASSERT(nonEmptyEntryCount == m_propertyTable->keyCount);
+}
+
+#endif // DO_PROPERTYMAP_CONSTENCY_CHECK
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/StructureID.h b/JavaScriptCore/runtime/StructureID.h
new file mode 100644
index 0000000..4f45dac
--- /dev/null
+++ b/JavaScriptCore/runtime/StructureID.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 StructureID_h
+#define StructureID_h
+
+#include "JSType.h"
+#include "JSValue.h"
+#include "PropertyMapHashTable.h"
+#include "StructureIDChain.h"
+#include "StructureIDTransitionTable.h"
+#include "TypeInfo.h"
+#include "identifier.h"
+#include "ustring.h"
+#include <wtf/HashFunctions.h>
+#include <wtf/HashTraits.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+#ifndef NDEBUG
+#define DUMP_PROPERTYMAP_STATS 0
+#else
+#define DUMP_PROPERTYMAP_STATS 0
+#endif
+
+namespace JSC {
+
+    class PropertyNameArray;
+    class PropertyNameArrayData;
+
+    class StructureID : public RefCounted<StructureID> {
+    public:
+        friend class CTI;
+        static PassRefPtr<StructureID> create(JSValue* prototype, const TypeInfo& typeInfo)
+        {
+            return adoptRef(new StructureID(prototype, typeInfo));
+        }
+
+        static void startIgnoringLeaks();
+        static void stopIgnoringLeaks();
+
+        static void dumpStatistics();
+
+        static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
+        static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset);
+        static PassRefPtr<StructureID> removePropertyTransition(StructureID*, const Identifier& propertyName, size_t& offset);
+        static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
+        static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
+        static PassRefPtr<StructureID> fromDictionaryTransition(StructureID*);
+
+        ~StructureID();
+
+        void mark()
+        {
+            if (!m_prototype->marked())
+                m_prototype->mark();
+        }
+
+        // These should be used with caution.  
+        size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
+        size_t removePropertyWithoutTransition(const Identifier& propertyName);
+        void setPrototypeWithoutTransition(JSValue* prototype) { m_prototype = prototype; }
+
+        bool isDictionary() const { return m_isDictionary; }
+
+        const TypeInfo& typeInfo() const { return m_typeInfo; }
+
+        // For use when first creating a new structure.
+        TypeInfo& mutableTypeInfo() { return m_typeInfo; }
+
+        JSValue* storedPrototype() const { return m_prototype; }
+        JSValue* prototypeForLookup(ExecState*); 
+
+        StructureID* previousID() const { return m_previous.get(); }
+
+        StructureIDChain* createCachedPrototypeChain();
+        void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+        StructureIDChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
+
+        void setCachedTransistionOffset(size_t offset) { m_cachedTransistionOffset = offset; }
+        size_t cachedTransistionOffset() const { return m_cachedTransistionOffset; }
+
+        void growPropertyStorageCapacity();
+        size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
+        size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_deletedOffsets.size() : 0; }
+
+        size_t get(const Identifier& propertyName) const;
+        size_t get(const Identifier& propertyName, unsigned& attributes) const;
+        void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
+
+        bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
+        void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
+
+        bool isEmpty() const { return !m_propertyTable; }
+
+    private:
+        StructureID(JSValue* prototype, const TypeInfo&);
+
+        size_t put(const Identifier& propertyName, unsigned attributes);
+        size_t remove(const Identifier& propertyName);
+        void getEnumerablePropertyNamesInternal(PropertyNameArray&) const;
+
+        void expandPropertyMapHashTable();
+        void rehashPropertyMapHashTable();
+        void rehashPropertyMapHashTable(unsigned newTableSize);
+        void createPropertyMapHashTable();
+        void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
+        void checkConsistency();
+
+        PropertyMapHashTable* copyPropertyTable();
+
+        void clearEnumerationCache();
+
+        static const unsigned emptyEntryIndex = 0;
+    
+        static const size_t s_maxTransitionLength = 64;
+
+        TypeInfo m_typeInfo;
+
+        JSValue* m_prototype;
+        RefPtr<StructureIDChain> m_cachedPrototypeChain;
+
+        RefPtr<StructureID> m_previous;
+        UString::Rep* m_nameInPrevious;
+
+        size_t m_transitionCount;
+        union {
+            StructureID* singleTransition;
+            StructureIDTransitionTable* table;
+        } m_transitions;
+
+        RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
+
+        PropertyMapHashTable* m_propertyTable;
+        Vector<unsigned> m_deletedOffsets;
+
+        size_t m_propertyStorageCapacity;
+
+        size_t m_cachedTransistionOffset;
+
+        bool m_isDictionary : 1;
+        bool m_hasGetterSetterProperties : 1;
+        bool m_usingSingleTransitionSlot : 1;
+        unsigned m_attributesInPrevious : 5;
+    };
+
+    inline size_t StructureID::get(const Identifier& propertyName) const
+    {
+        ASSERT(!propertyName.isNull());
+
+        if (!m_propertyTable)
+            return WTF::notFound;
+
+        UString::Rep* rep = propertyName._ustring.rep();
+
+        unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numProbes;
+#endif
+
+        unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            return WTF::notFound;
+
+        if (rep == m_propertyTable->entries()[entryIndex - 1].key)
+            return m_propertyTable->entries()[entryIndex - 1].offset;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numCollisions;
+#endif
+
+        unsigned k = 1 | WTF::doubleHash(rep->computedHash());
+
+        while (1) {
+            i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+            ++numRehashes;
+#endif
+
+            entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+            if (entryIndex == emptyEntryIndex)
+                return WTF::notFound;
+
+            if (rep == m_propertyTable->entries()[entryIndex - 1].key)
+                return m_propertyTable->entries()[entryIndex - 1].offset;
+        }
+    }
+
+} // namespace JSC
+
+#endif // StructureID_h
diff --git a/JavaScriptCore/runtime/StructureIDChain.cpp b/JavaScriptCore/runtime/StructureIDChain.cpp
new file mode 100644
index 0000000..83d9254
--- /dev/null
+++ b/JavaScriptCore/runtime/StructureIDChain.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "StructureIDChain.h"
+
+#include "JSObject.h"
+#include "StructureID.h"
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+StructureIDChain::StructureIDChain(StructureID* structureID)
+{
+    size_t size = 1;
+
+    StructureID* tmp = structureID;
+    while (!tmp->storedPrototype()->isNull()) {
+        ++size;
+        tmp = asCell(tmp->storedPrototype())->structureID();
+    }
+    
+    m_vector.set(new RefPtr<StructureID>[size + 1]);
+
+    size_t i;
+    for (i = 0; i < size - 1; ++i) {
+        m_vector[i] = structureID;
+        structureID = asObject(structureID->storedPrototype())->structureID();
+    }
+    m_vector[i] = structureID;
+    m_vector[i + 1] = 0;
+}
+
+bool structureIDChainsAreEqual(StructureIDChain* chainA, StructureIDChain* chainB)
+{
+    if (!chainA || !chainB)
+        return false;
+
+    RefPtr<StructureID>* a = chainA->head();
+    RefPtr<StructureID>* b = chainB->head();
+    while (1) {
+        if (*a != *b)
+            return false;
+        if (!*a)
+            return true;
+        a++;
+        b++;
+    }
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/StructureIDChain.h b/JavaScriptCore/runtime/StructureIDChain.h
new file mode 100644
index 0000000..2d554a7
--- /dev/null
+++ b/JavaScriptCore/runtime/StructureIDChain.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 StructureIDChain_h
+#define StructureIDChain_h
+
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+    class StructureID;
+
+    class StructureIDChain : public RefCounted<StructureIDChain> {
+    public:
+        static PassRefPtr<StructureIDChain> create(StructureID* structureID) { return adoptRef(new StructureIDChain(structureID)); }
+
+        RefPtr<StructureID>* head() { return m_vector.get(); }
+
+    private:
+        StructureIDChain(StructureID* structureID);
+
+        OwnArrayPtr<RefPtr<StructureID> > m_vector;
+    };
+
+    bool structureIDChainsAreEqual(StructureIDChain*, StructureIDChain*);
+
+} // namespace JSC
+
+#endif // StructureIDChain_h
diff --git a/JavaScriptCore/runtime/StructureIDTransitionTable.h b/JavaScriptCore/runtime/StructureIDTransitionTable.h
new file mode 100644
index 0000000..dd65971
--- /dev/null
+++ b/JavaScriptCore/runtime/StructureIDTransitionTable.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 StructureIDTransitionTable_h
+#define StructureIDTransitionTable_h
+
+#include "ustring.h"
+#include <wtf/HashFunctions.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashTraits.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+    class StructureID;
+
+    struct StructureIDTransitionTableHash {
+        typedef std::pair<RefPtr<UString::Rep>, unsigned> Key;
+        static unsigned hash(const Key& p)
+        {
+            return p.first->computedHash();
+        }
+
+        static bool equal(const Key& a, const Key& b)
+        {
+            return a == b;
+        }
+
+        static const bool safeToCompareToEmptyOrDeleted = true;
+    };
+
+    struct StructureIDTransitionTableHashTraits {
+        typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
+        typedef WTF::GenericHashTraits<unsigned> SecondTraits;
+        typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
+
+        static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
+        static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
+
+        static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
+
+        static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
+        static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
+    };
+
+    typedef HashMap<StructureIDTransitionTableHash::Key, StructureID*, StructureIDTransitionTableHash, StructureIDTransitionTableHashTraits> StructureIDTransitionTable;
+
+} // namespace JSC
+
+#endif // StructureIDTransitionTable_h
diff --git a/JavaScriptCore/runtime/SymbolTable.h b/JavaScriptCore/runtime/SymbolTable.h
new file mode 100644
index 0000000..d730d58
--- /dev/null
+++ b/JavaScriptCore/runtime/SymbolTable.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS 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 SymbolTable_h
+#define SymbolTable_h
+
+#include "JSObject.h"
+#include "ustring.h"
+#include <wtf/AlwaysInline.h>
+
+namespace JSC {
+
+    static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
+
+    // The bit twiddling in this class assumes that every register index is a
+    // reasonably small positive or negative number, and therefore has its high
+    // four bits all set or all unset.
+
+    struct SymbolTableEntry {
+        SymbolTableEntry()
+            : m_bits(0)
+        {
+        }
+
+        SymbolTableEntry(int index)
+        {
+            ASSERT(isValidIndex(index));
+            pack(index, false, false);
+        }
+
+        SymbolTableEntry(int index, unsigned attributes)
+        {
+            ASSERT(isValidIndex(index));
+            pack(index, attributes & ReadOnly, attributes & DontEnum);
+        }
+        
+        bool isNull() const
+        {
+            return !m_bits;
+        }
+
+        int getIndex() const
+        {
+            return m_bits >> FlagBits;
+        }
+
+        unsigned getAttributes() const
+        {
+            unsigned attributes = 0;
+            if (m_bits & ReadOnlyFlag)
+                attributes |= ReadOnly;
+            if (m_bits & DontEnumFlag)
+                attributes |= DontEnum;
+            return attributes;
+        }
+
+        void setAttributes(unsigned attributes)
+        {
+            pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
+        }
+
+        bool isReadOnly() const
+        {
+            return m_bits & ReadOnlyFlag;
+        }
+
+    private:
+        static const unsigned ReadOnlyFlag = 0x1;
+        static const unsigned DontEnumFlag = 0x2;
+        static const unsigned NotNullFlag = 0x4;
+        static const unsigned FlagBits = 3;
+
+        void pack(int index, bool readOnly, bool dontEnum)
+        {
+            m_bits = (index << FlagBits) | NotNullFlag;
+            if (readOnly)
+                m_bits |= ReadOnlyFlag;
+            if (dontEnum)
+                m_bits |= DontEnumFlag;
+        }
+        
+        bool isValidIndex(int index)
+        {
+            return ((index << FlagBits) >> FlagBits) == index;
+        }
+
+        int m_bits;
+    };
+
+    struct SymbolTableIndexHashTraits {
+        typedef SymbolTableEntry TraitType;
+        static SymbolTableEntry emptyValue() { return SymbolTableEntry(); }
+        static const bool emptyValueIsZero = true;
+        static const bool needsDestruction = false;
+    };
+
+    typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;
+
+} // namespace JSC
+
+#endif // SymbolTable_h
diff --git a/JavaScriptCore/runtime/Tracing.d b/JavaScriptCore/runtime/Tracing.d
new file mode 100644
index 0000000..b9efaff
--- /dev/null
+++ b/JavaScriptCore/runtime/Tracing.d
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+provider JavaScriptCore
+{
+    probe gc__begin();
+    probe gc__marked();
+    probe gc__end(int, int);
+    
+    probe profile__will_execute(int, char*, char*, int);
+    probe profile__did_execute(int, char*, char*, int);
+};
+
+#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore provider
+#pragma D attributes Private/Private/Unknown provider JavaScriptCore module
+#pragma D attributes Private/Private/Unknown provider JavaScriptCore function
+#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore name
+#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore args
diff --git a/JavaScriptCore/runtime/Tracing.h b/JavaScriptCore/runtime/Tracing.h
new file mode 100644
index 0000000..e544f66
--- /dev/null
+++ b/JavaScriptCore/runtime/Tracing.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Tracing_h
+#define Tracing_h
+
+#if HAVE(DTRACE)
+#include "TracingDtrace.h"
+#else
+
+#define JAVASCRIPTCORE_GC_BEGIN()
+#define JAVASCRIPTCORE_GC_BEGIN_ENABLED() 0
+
+#define JAVASCRIPTCORE_GC_END(arg0, arg1)
+#define JAVASCRIPTCORE_GC_END_ENABLED() 0
+
+#define JAVASCRIPTCORE_GC_MARKED()
+#define JAVASCRIPTCORE_GC_MARKED_ENABLED() 0
+
+#define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(arg0, arg1, arg2, arg3)
+#define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED() 0
+
+#define JAVASCRIPTCORE_PROFILE_DID_EXECUTE(arg0, arg1, arg2, arg3)
+#define JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED() 0
+
+#endif
+
+#endif // Tracing_h
