auto import from //depot/cupcake/@135843
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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003 Peter Kelly ([email protected])
+ *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+ *
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003 Peter Kelly ([email protected])
+ *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+ *
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ * 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 ([email protected])
+ * 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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Eric Seidel ([email protected])
+ *
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003 Peter Kelly ([email protected])
+ *  Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+ *
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *
+ * 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 <[email protected]>
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Eric Seidel ([email protected])
+ *
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2001 Peter Kelly ([email protected])
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007 Cameron Zwarich ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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 ([email protected])
+ *  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