summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/javascriptcore/JavaScriptCore/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/runtime')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp83
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h230
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp284
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h247
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp85
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h40
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp1055
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h41
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h55
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp78
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h44
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp35
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h46
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp83
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h35
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.cpp65
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h91
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h62
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp1376
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h287
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h90
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.cpp39
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h91
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp86
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.h63
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp65
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h96
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp183
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h43
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp101
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h60
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp118
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h67
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp1105
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h47
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp128
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h73
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp73
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h44
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp33
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h38
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp68
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h37
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp211
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h57
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp133
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h48
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp148
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h46
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp84
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h75
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp49
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h46
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp268
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h144
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp72
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.h40
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp71
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h66
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp184
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h98
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp1073
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h130
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp97
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h115
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp210
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h300
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp215
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h138
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp254
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h164
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp464
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h426
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp439
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.h60
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp103
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h790
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.cpp254
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.h104
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp124
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h97
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp137
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h480
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp766
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h58
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp546
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h629
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp90
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h116
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp79
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h68
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp171
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h218
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h42
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h72
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp87
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h420
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp70
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h164
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp36
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h59
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp449
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h110
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp82
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h265
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp242
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h45
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp73
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h51
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp43
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h44
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeFunctionWrapper.h39
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp123
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h55
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp51
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h44
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp445
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h35
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp73
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h41
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp135
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h37
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp121
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h334
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h90
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp50
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h113
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp45
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h203
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h215
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp57
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h45
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PutPropertySlot.h77
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp283
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h89
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp392
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h82
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h87
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp168
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h83
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp123
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h38
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp68
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h240
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h39
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp128
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h74
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp91
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h40
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp112
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h73
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h55
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp895
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h42
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp1156
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h242
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp66
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h52
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h73
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h126
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp159
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h76
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.d40
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h50
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp1781
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h604
166 files changed, 30234 insertions, 0 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp
new file mode 100644
index 0000000..0b5d958
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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
+{
+ if (startIndex <= 0 || static_cast<unsigned>(startIndex) >= m_argCount) {
+ result = ArgList(m_args, 0);
+ return;
+ }
+ result = ArgList(m_args + startIndex, m_argCount - startIndex);
+}
+
+void MarkedArgumentBuffer::markLists(ListSet& markSet)
+{
+ ListSet::iterator end = markSet.end();
+ for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
+ MarkedArgumentBuffer* list = *it;
+
+ iterator end2 = list->end();
+ for (iterator it2 = list->begin(); it2 != end2; ++it2)
+ if (!(*it2).marked())
+ (*it2).mark();
+ }
+}
+
+void MarkedArgumentBuffer::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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h
new file mode 100644
index 0000000..0899e85
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008, 2009 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 MarkedArgumentBuffer : public Noncopyable {
+ private:
+ static const unsigned inlineCapacity = 8;
+ typedef Vector<Register, inlineCapacity> VectorType;
+ typedef HashSet<MarkedArgumentBuffer*> 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.
+ MarkedArgumentBuffer()
+ : m_isUsingInlineBuffer(true)
+ , 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.
+ MarkedArgumentBuffer(Register* buffer, size_t size)
+ : m_buffer(buffer)
+ , m_size(size)
+ , m_isUsingInlineBuffer(true)
+ , 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
+ }
+
+ ~MarkedArgumentBuffer()
+ {
+ if (m_markSet)
+ m_markSet->remove(this);
+ }
+
+ size_t size() const { return m_size; }
+ bool isEmpty() const { return !m_size; }
+
+ JSValue at(size_t i) const
+ {
+ if (i < m_size)
+ return m_buffer[i].jsValue();
+ return jsUndefined();
+ }
+
+ void clear()
+ {
+ m_vector.clear();
+ m_buffer = 0;
+ m_size = 0;
+ }
+
+ void append(JSValue v)
+ {
+ ASSERT(!m_isReadOnly);
+
+ if (m_isUsingInlineBuffer && 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;
+ m_isUsingInlineBuffer = false;
+ }
+ }
+
+ void removeLast()
+ {
+ ASSERT(m_size);
+ m_size--;
+ m_vector.removeLast();
+ }
+
+ JSValue last()
+ {
+ ASSERT(m_size);
+ return m_buffer[m_size - 1].jsValue();
+ }
+
+ 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;
+ bool m_isUsingInlineBuffer;
+
+ 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);
+ };
+
+ class ArgList {
+ friend class JIT;
+ public:
+ typedef JSValue* iterator;
+ typedef const JSValue* const_iterator;
+
+ ArgList()
+ : m_args(0)
+ , m_argCount(0)
+ {
+ }
+
+ ArgList(JSValue* args, unsigned argCount)
+ : m_args(args)
+ , m_argCount(argCount)
+ {
+ }
+
+ ArgList(Register* args, int argCount)
+ : m_args(reinterpret_cast<JSValue*>(args))
+ , m_argCount(argCount)
+ {
+ ASSERT(argCount >= 0);
+ }
+
+ ArgList(const MarkedArgumentBuffer& args)
+ : m_args(reinterpret_cast<JSValue*>(const_cast<Register*>(args.begin())))
+ , m_argCount(args.size())
+ {
+ }
+
+ JSValue at(size_t idx) const
+ {
+ if (idx < m_argCount)
+ return m_args[idx];
+ return jsUndefined();
+ }
+
+ bool isEmpty() const { return !m_argCount; }
+
+ size_t size() const { return m_argCount; }
+
+ iterator begin() { return m_args; }
+ iterator end() { return m_args + m_argCount; }
+
+ const_iterator begin() const { return m_args; }
+ const_iterator end() const { return m_args + m_argCount; }
+
+ void getSlice(int startIndex, ArgList& result) const;
+ private:
+ JSValue* m_args;
+ size_t m_argCount;
+ };
+
+} // namespace JSC
+
+#endif // ArgList_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp
new file mode 100644
index 0000000..7cb4fe9
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "Arguments.h"
+
+#include "JSActivation.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+
+using namespace std;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(Arguments);
+
+const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
+
+Arguments::~Arguments()
+{
+ if (d->extraArguments != d->extraArgumentsFixedBuffer)
+ delete [] d->extraArguments;
+}
+
+void Arguments::mark()
+{
+ JSObject::mark();
+
+ if (d->registerArray) {
+ for (unsigned i = 0; i < d->numParameters; ++i) {
+ if (!d->registerArray[i].marked())
+ d->registerArray[i].mark();
+ }
+ }
+
+ if (d->extraArguments) {
+ unsigned numExtraArguments = d->numArguments - d->numParameters;
+ for (unsigned i = 0; i < numExtraArguments; ++i) {
+ if (!d->extraArguments[i].marked())
+ d->extraArguments[i].mark();
+ }
+ }
+
+ if (!d->callee->marked())
+ d->callee->mark();
+
+ if (d->activation && !d->activation->marked())
+ d->activation->mark();
+}
+
+void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
+{
+ if (UNLIKELY(d->overrodeLength)) {
+ unsigned length = min(get(exec, exec->propertyNames().length).toUInt32(exec), maxSize);
+ for (unsigned i = 0; i < length; i++)
+ buffer[i] = get(exec, i);
+ return;
+ }
+
+ if (LIKELY(!d->deletedArguments)) {
+ unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
+ unsigned i = 0;
+ for (; i < parametersLength; ++i)
+ buffer[i] = d->registers[d->firstParameterIndex + i].jsValue();
+ for (; i < d->numArguments; ++i)
+ buffer[i] = d->extraArguments[i - d->numParameters].jsValue();
+ return;
+ }
+
+ unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
+ unsigned i = 0;
+ for (; i < parametersLength; ++i) {
+ if (!d->deletedArguments[i])
+ buffer[i] = d->registers[d->firstParameterIndex + i].jsValue();
+ else
+ buffer[i] = get(exec, i);
+ }
+ for (; i < d->numArguments; ++i) {
+ if (!d->deletedArguments[i])
+ buffer[i] = d->extraArguments[i - d->numParameters].jsValue();
+ else
+ buffer[i] = get(exec, i);
+ }
+}
+
+void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
+{
+ if (UNLIKELY(d->overrodeLength)) {
+ unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
+ for (unsigned i = 0; i < length; i++)
+ args.append(get(exec, i));
+ return;
+ }
+
+ 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());
+ for (; i < d->numArguments; ++i)
+ args.append(d->extraArguments[i - d->numParameters].jsValue());
+ 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());
+ else
+ args.append(get(exec, i));
+ }
+ for (; i < d->numArguments; ++i) {
+ if (!d->deletedArguments[i])
+ args.append(d->extraArguments[i - d->numParameters].jsValue());
+ 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());
+ 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());
+ 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] = JSValue(value);
+ else
+ d->extraArguments[i - d->numParameters] = JSValue(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] = JSValue(value);
+ else
+ d->extraArguments[i - d->numParameters] = JSValue(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, bool checkDontDelete)
+{
+ 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)), checkDontDelete);
+}
+
+bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+{
+ 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, checkDontDelete);
+}
+
+bool Arguments::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+{
+ if ((propertyName == exec->propertyNames().length)
+ || (propertyName == exec->propertyNames().callee)) {
+ attributes = DontEnum;
+ return true;
+ }
+ return JSObject::getPropertyAttributes(exec, propertyName, attributes);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h
new file mode 100644
index 0000000..dc54dac
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef Arguments_h
+#define Arguments_h
+
+#include "JSActivation.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "Interpreter.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];
+
+ JSObject* 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*, MarkedArgumentBuffer&);
+
+ uint32_t numProvidedArguments(ExecState* exec) const
+ {
+ if (UNLIKELY(d->overrodeLength))
+ return get(exec, exec->propertyNames().length).toUInt32(exec);
+ return d->numArguments;
+ }
+
+ void copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize);
+ void copyRegisters();
+ bool isTornOff() const { return d->registerArray; }
+ void setActivation(JSActivation* activation)
+ {
+ d->activation = activation;
+ d->registers = &activation->registerAt(0);
+ }
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+
+ private:
+ void getArgumentsData(CallFrame*, JSObject*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+ virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
+ virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+
+ 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, JSObject*& callee, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc)
+ {
+ callee = callFrame->callee();
+
+ int numParameters;
+ if (callee->isObject(&JSFunction::info)) {
+ CodeBlock* codeBlock = &JSC::asFunction(callee)->body()->generatedBytecode();
+ numParameters = codeBlock->m_numParameters;
+ } else {
+ numParameters = 0;
+ }
+ 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)
+ {
+ JSObject* callee;
+ ptrdiff_t firstParameterIndex;
+ Register* argv;
+ int numArguments;
+ getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
+
+ if (callee->isObject(&JSFunction::info))
+ d->numParameters = JSC::asFunction(callee)->body()->parameterCount();
+ else
+ d->numParameters = 0;
+ 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)
+ {
+ if (callFrame->callee() && callFrame->callee()->isObject(&JSC::JSFunction::info))
+ ASSERT(!asFunction(callFrame->callee())->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;
+ if (callFrame->callee() && !callFrame->callee()->isObject(&JSC::JSFunction::info))
+ ++argv; // ### off-by-one issue with native functions
+ 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().m_numParameters - 1;
+ size_t numVars = d()->functionBody->generatedBytecode().m_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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp
new file mode 100644
index 0000000..e96bdfc
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+#include "config.h"
+#include "ArrayConstructor.h"
+
+#include "ArrayPrototype.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "Lookup.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
+
+ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> 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(0).isNumber()) {
+ uint32_t n = args.at(0).toUInt32(exec);
+ if (n != args.at(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->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 JSC_HOST_CALL 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h
new file mode 100644
index 0000000..8300d8c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ArrayConstructor_h
+#define ArrayConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class ArrayPrototype;
+
+ class ArrayConstructor : public InternalFunction {
+ public:
+ ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*);
+
+ virtual ConstructType getConstructData(ConstructData&);
+ virtual CallType getCallData(CallData&);
+ };
+
+} // namespace JSC
+
+#endif // ArrayConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp
new file mode 100644
index 0000000..807e59a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -0,0 +1,1055 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * 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 "CodeBlock.h"
+#include "CachedCall.h"
+#include "Interpreter.h"
+#include "JIT.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 JSC_HOST_CALL arrayProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+
+}
+
+#include "ArrayPrototype.lut.h"
+
+namespace JSC {
+
+static inline bool isNumericCompareFunction(CallType callType, const CallData& callData)
+{
+ if (callType != CallTypeJS)
+ return false;
+
+#if ENABLE(JIT)
+ // If the JIT is enabled then we need to preserve the invariant that every
+ // function with a CodeBlock also has JIT code.
+ callData.js.functionBody->jitCode(callData.js.scopeChain);
+ CodeBlock& codeBlock = callData.js.functionBody->generatedBytecode();
+#else
+ CodeBlock& codeBlock = callData.js.functionBody->bytecode(callData.js.scopeChain);
+#endif
+
+ return codeBlock.isNumericCompareFunction();
+}
+
+// ------------------------------ 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
+ reduce arrayProtoFuncReduce DontEnum|Function 1
+ reduceRight arrayProtoFuncReduceRight DontEnum|Function 1
+ map arrayProtoFuncMap DontEnum|Function 1
+@end
+*/
+
+// ECMA 15.4.4
+ArrayPrototype::ArrayPrototype(PassRefPtr<Structure> 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 JSValue();
+ 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 JSC_HOST_CALL 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() >= MaxSecondaryThreadReentryDepth) {
+ if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
+ 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 JSC_HOST_CALL 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() >= MaxSecondaryThreadReentryDepth) {
+ if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
+ 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 JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
+ if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
+ if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
+ 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(0).isUndefined() ? UString(&comma, 1) : args.at(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 JSC_HOST_CALL 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)) {
+ unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
+ JSObject* curObject = curArg.toObject(exec);
+ for (unsigned k = 0; k < length; ++k) {
+ if (JSValue v = getProperty(exec, curObject, k))
+ arr->put(exec, n, v);
+ n++;
+ }
+ } else {
+ arr->put(exec, n, curArg);
+ n++;
+ }
+ if (it == end)
+ break;
+ curArg = (*it);
+ ++it;
+ }
+ arr->setLength(n);
+ return arr;
+}
+
+JSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ if (isJSArray(&exec->globalData(), 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 JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ if (isJSArray(&exec->globalData(), thisValue) && args.size() == 1) {
+ JSArray* array = asArray(thisValue);
+ array->push(exec, *args.begin());
+ 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(n));
+ length += args.size();
+ putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
+ return jsNumber(exec, length);
+}
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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(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(1).isUndefined())
+ end = length;
+ else {
+ end = args.at(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 JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+
+ if (thisObj->classInfo() == &JSArray::info) {
+ if (isNumericCompareFunction(callType, callData))
+ asArray(thisObj)->sortNumeric(exec, function, callType, callData);
+ else 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) {
+ MarkedArgumentBuffer 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 JSC_HOST_CALL 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(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(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(k + 2));
+
+ putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
+ return result;
+}
+
+JSValue JSC_HOST_CALL 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(k));
+ JSValue result = jsNumber(exec, length + nrArgs);
+ putProperty(exec, thisObj, exec->propertyNames().length, result);
+ return result;
+}
+
+JSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
+ JSArray* resultArray = constructEmptyArray(exec);
+
+ unsigned filterIndex = 0;
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ unsigned k = 0;
+ if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+ JSFunction* f = asFunction(function);
+ JSArray* array = asArray(thisObj);
+ CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+ for (; k < length && !exec->hadException(); ++k) {
+ if (!array->canGetIndex(k))
+ break;
+ JSValue v = array->getIndex(k);
+ cachedCall.setThis(applyThis);
+ cachedCall.setArgument(0, v);
+ cachedCall.setArgument(1, jsNumber(exec, k));
+ cachedCall.setArgument(2, thisObj);
+
+ JSValue result = cachedCall.call();
+ if (result.toBoolean(exec))
+ resultArray->put(exec, filterIndex++, v);
+ }
+ if (k == length)
+ return resultArray;
+ }
+ for (; k < length && !exec->hadException(); ++k) {
+ PropertySlot slot(thisObj);
+
+ if (!thisObj->getPropertySlot(exec, k, slot))
+ continue;
+
+ JSValue v = slot.getValue(exec, k);
+
+ MarkedArgumentBuffer 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 JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
+
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+
+ JSArray* resultArray = constructEmptyArray(exec, length);
+ unsigned k = 0;
+ if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+ JSFunction* f = asFunction(function);
+ JSArray* array = asArray(thisObj);
+ CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+ for (; k < length && !exec->hadException(); ++k) {
+ if (UNLIKELY(!array->canGetIndex(k)))
+ break;
+
+ cachedCall.setThis(applyThis);
+ cachedCall.setArgument(0, array->getIndex(k));
+ cachedCall.setArgument(1, jsNumber(exec, k));
+ cachedCall.setArgument(2, thisObj);
+
+ resultArray->JSArray::put(exec, k, cachedCall.call());
+ }
+ }
+ for (; k < length && !exec->hadException(); ++k) {
+ PropertySlot slot(thisObj);
+ if (!thisObj->getPropertySlot(exec, k, slot))
+ continue;
+
+ JSValue v = slot.getValue(exec, k);
+
+ MarkedArgumentBuffer 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 JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
+
+ JSValue result = jsBoolean(true);
+
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ unsigned k = 0;
+ if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+ JSFunction* f = asFunction(function);
+ JSArray* array = asArray(thisObj);
+ CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+ for (; k < length && !exec->hadException(); ++k) {
+ if (UNLIKELY(!array->canGetIndex(k)))
+ break;
+
+ cachedCall.setThis(applyThis);
+ cachedCall.setArgument(0, array->getIndex(k));
+ cachedCall.setArgument(1, jsNumber(exec, k));
+ cachedCall.setArgument(2, thisObj);
+
+ if (!cachedCall.call().toBoolean(exec))
+ return jsBoolean(false);
+ }
+ }
+ for (; k < length && !exec->hadException(); ++k) {
+ PropertySlot slot(thisObj);
+
+ if (!thisObj->getPropertySlot(exec, k, slot))
+ continue;
+
+ MarkedArgumentBuffer 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 JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
+
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ unsigned k = 0;
+ if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+ JSFunction* f = asFunction(function);
+ JSArray* array = asArray(thisObj);
+ CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+ for (; k < length && !exec->hadException(); ++k) {
+ if (UNLIKELY(!array->canGetIndex(k)))
+ break;
+
+ cachedCall.setThis(applyThis);
+ cachedCall.setArgument(0, array->getIndex(k));
+ cachedCall.setArgument(1, jsNumber(exec, k));
+ cachedCall.setArgument(2, thisObj);
+
+ cachedCall.call();
+ }
+ }
+ for (; k < length && !exec->hadException(); ++k) {
+ PropertySlot slot(thisObj);
+ if (!thisObj->getPropertySlot(exec, k, slot))
+ continue;
+
+ MarkedArgumentBuffer 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 JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
+
+ JSValue result = jsBoolean(false);
+
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ unsigned k = 0;
+ if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+ JSFunction* f = asFunction(function);
+ JSArray* array = asArray(thisObj);
+ CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+ for (; k < length && !exec->hadException(); ++k) {
+ if (UNLIKELY(!array->canGetIndex(k)))
+ break;
+
+ cachedCall.setThis(applyThis);
+ cachedCall.setArgument(0, array->getIndex(k));
+ cachedCall.setArgument(1, jsNumber(exec, k));
+ cachedCall.setArgument(2, thisObj);
+
+ if (cachedCall.call().toBoolean(exec))
+ return jsBoolean(true);
+ }
+ }
+ for (; k < length && !exec->hadException(); ++k) {
+ PropertySlot slot(thisObj);
+ if (!thisObj->getPropertySlot(exec, k, slot))
+ continue;
+
+ MarkedArgumentBuffer 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 JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ unsigned i = 0;
+ JSValue rv;
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (!length && args.size() == 1)
+ return throwError(exec, TypeError);
+ JSArray* array = 0;
+ if (isJSArray(&exec->globalData(), thisObj))
+ array = asArray(thisObj);
+
+ if (args.size() >= 2)
+ rv = args.at(1);
+ else if (array && array->canGetIndex(0)){
+ rv = array->getIndex(0);
+ i = 1;
+ } else {
+ for (i = 0; i < length; i++) {
+ rv = getProperty(exec, thisObj, i);
+ if (rv)
+ break;
+ }
+ if (!rv)
+ return throwError(exec, TypeError);
+ i++;
+ }
+
+ if (callType == CallTypeJS && array) {
+ CachedCall cachedCall(exec, asFunction(function), 4, exec->exceptionSlot());
+ for (; i < length && !exec->hadException(); ++i) {
+ cachedCall.setThis(jsNull());
+ cachedCall.setArgument(0, rv);
+ JSValue v;
+ if (LIKELY(array->canGetIndex(i)))
+ v = array->getIndex(i);
+ else
+ break; // length has been made unsafe while we enumerate fallback to slow path
+ cachedCall.setArgument(1, v);
+ cachedCall.setArgument(2, jsNumber(exec, i));
+ cachedCall.setArgument(3, array);
+ rv = cachedCall.call();
+ }
+ if (i == length) // only return if we reached the end of the array
+ return rv;
+ }
+
+ for (; i < length && !exec->hadException(); ++i) {
+ JSValue prop = getProperty(exec, thisObj, i);
+ if (!prop)
+ continue;
+
+ MarkedArgumentBuffer eachArguments;
+ eachArguments.append(rv);
+ eachArguments.append(prop);
+ eachArguments.append(jsNumber(exec, i));
+ eachArguments.append(thisObj);
+
+ rv = call(exec, function, callType, callData, jsNull(), eachArguments);
+ }
+ return rv;
+}
+
+JSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ JSValue function = args.at(0);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ unsigned i = 0;
+ JSValue rv;
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (!length && args.size() == 1)
+ return throwError(exec, TypeError);
+ JSArray* array = 0;
+ if (isJSArray(&exec->globalData(), thisObj))
+ array = asArray(thisObj);
+
+ if (args.size() >= 2)
+ rv = args.at(1);
+ else if (array && array->canGetIndex(length - 1)){
+ rv = array->getIndex(length - 1);
+ i = 1;
+ } else {
+ for (i = 0; i < length; i++) {
+ rv = getProperty(exec, thisObj, length - i - 1);
+ if (rv)
+ break;
+ }
+ if (!rv)
+ return throwError(exec, TypeError);
+ i++;
+ }
+
+ if (callType == CallTypeJS && array) {
+ CachedCall cachedCall(exec, asFunction(function), 4, exec->exceptionSlot());
+ for (; i < length && !exec->hadException(); ++i) {
+ unsigned idx = length - i - 1;
+ cachedCall.setThis(jsNull());
+ cachedCall.setArgument(0, rv);
+ if (UNLIKELY(!array->canGetIndex(idx)))
+ break; // length has been made unsafe while we enumerate fallback to slow path
+ cachedCall.setArgument(1, array->getIndex(idx));
+ cachedCall.setArgument(2, jsNumber(exec, idx));
+ cachedCall.setArgument(3, array);
+ rv = cachedCall.call();
+ }
+ if (i == length) // only return if we reached the end of the array
+ return rv;
+ }
+
+ for (; i < length && !exec->hadException(); ++i) {
+ unsigned idx = length - i - 1;
+ JSValue prop = getProperty(exec, thisObj, idx);
+ if (!prop)
+ continue;
+
+ MarkedArgumentBuffer eachArguments;
+ eachArguments.append(rv);
+ eachArguments.append(prop);
+ eachArguments.append(jsNumber(exec, idx));
+ eachArguments.append(thisObj);
+
+ rv = call(exec, function, callType, callData, jsNull(), eachArguments);
+ }
+ return rv;
+}
+
+JSValue JSC_HOST_CALL 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(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(0);
+ for (; index < length; ++index) {
+ JSValue e = getProperty(exec, thisObj, index);
+ if (!e)
+ continue;
+ if (JSValue::strictEqual(searchElement, e))
+ return jsNumber(exec, index);
+ }
+
+ return jsNumber(exec, -1);
+}
+
+JSValue JSC_HOST_CALL 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(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(0);
+ for (; index >= 0; --index) {
+ JSValue e = getProperty(exec, thisObj, index);
+ if (!e)
+ continue;
+ if (JSValue::strictEqual(searchElement, e))
+ return jsNumber(exec, index);
+ }
+
+ return jsNumber(exec, -1);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h
new file mode 100644
index 0000000..2165089
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ArrayPrototype_h
+#define ArrayPrototype_h
+
+#include "JSArray.h"
+#include "Lookup.h"
+
+namespace JSC {
+
+ class ArrayPrototype : public JSArray {
+ public:
+ explicit ArrayPrototype(PassRefPtr<Structure>);
+
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
new file mode 100644
index 0000000..b9f738f
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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 : public Noncopyable {
+ public:
+ BatchedTransitionOptimizer(JSObject* object)
+ : m_object(object)
+ {
+ if (!m_object->structure()->isDictionary())
+ m_object->setStructure(Structure::toDictionaryTransition(m_object->structure()));
+ }
+
+ ~BatchedTransitionOptimizer()
+ {
+ m_object->setStructure(Structure::fromDictionaryTransition(m_object->structure()));
+ }
+
+ private:
+ JSObject* m_object;
+ };
+
+} // namespace JSC
+
+#endif // BatchedTransitionOptimizer_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp
new file mode 100644
index 0000000..9fcba37
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "BooleanConstructor.h"
+
+#include "BooleanPrototype.h"
+#include "JSGlobalObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
+
+BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<Structure> 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(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 JSC_HOST_CALL callBooleanConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsBoolean(args.at(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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h
new file mode 100644
index 0000000..d9f51ab
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef BooleanConstructor_h
+#define BooleanConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class BooleanPrototype;
+
+ class BooleanConstructor : public InternalFunction {
+ public:
+ BooleanConstructor(ExecState*, PassRefPtr<Structure>, 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp
new file mode 100644
index 0000000..01f695a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "BooleanObject.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
+
+const ClassInfo BooleanObject::info = { "Boolean", 0, 0, 0 };
+
+BooleanObject::BooleanObject(PassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
+{
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h
new file mode 100644
index 0000000..cfd55fe
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef BooleanObject_h
+#define BooleanObject_h
+
+#include "JSWrapperObject.h"
+
+namespace JSC {
+
+ class BooleanObject : public JSWrapperObject {
+ public:
+ explicit BooleanObject(PassRefPtr<Structure>);
+
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp
new file mode 100644
index 0000000..703a568
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "BooleanPrototype.h"
+
+#include "Error.h"
+#include "JSFunction.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
+
+// Functions
+static JSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*, JSObject*, JSValue, const ArgList&);
+
+// ECMA 15.6.4
+
+BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+ : BooleanObject(structure)
+{
+ setInternalValue(jsBoolean(false));
+
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
+}
+
+
+// ------------------------------ Functions --------------------------
+
+// ECMA 15.6.4.2 + 15.6.4.3
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ if (thisValue.isBoolean())
+ return thisValue;
+
+ if (!thisValue.isObject(&BooleanObject::info))
+ return throwError(exec, TypeError);
+
+ return asBooleanObject(thisValue)->internalValue();
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h
new file mode 100644
index 0000000..16f80b5
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef BooleanPrototype_h
+#define BooleanPrototype_h
+
+#include "BooleanObject.h"
+
+namespace JSC {
+
+ class BooleanPrototype : public BooleanObject {
+ public:
+ BooleanPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ };
+
+} // namespace JSC
+
+#endif // BooleanPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.cpp
new file mode 100644
index 0000000..c89ebf8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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"
+#include "JSGlobalObject.h"
+
+#ifdef QT_BUILD_SCRIPT_LIB
+#include "Debugger.h"
+#include "DebuggerCallFrame.h"
+#endif
+
+namespace JSC {
+
+#ifdef QT_BUILD_SCRIPT_LIB
+JSValue JSC::NativeFuncWrapper::operator() (ExecState* exec, JSObject* jsobj, JSValue thisValue, const ArgList& argList) const
+{
+ Debugger* debugger = exec->lexicalGlobalObject()->debugger();
+ if (debugger)
+ debugger->callEvent(DebuggerCallFrame(exec), -1, -1);
+
+ JSValue returnValue = ptr(exec, jsobj, thisValue, argList);
+
+ if (debugger)
+ debugger->functionExit(returnValue, -1);
+
+ return returnValue;
+}
+#endif
+
+
+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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h
new file mode 100644
index 0000000..541779c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h
@@ -0,0 +1,91 @@
+/*
+ * 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 "NativeFunctionWrapper.h"
+
+namespace JSC {
+
+ class ArgList;
+ class ExecState;
+ class FunctionBodyNode;
+ class JSObject;
+ class JSValue;
+ class ScopeChainNode;
+
+ enum CallType {
+ CallTypeNone,
+ CallTypeHost,
+ CallTypeJS
+ };
+
+ typedef JSValue (JSC_HOST_CALL *NativeFunction)(ExecState*, JSObject*, JSValue thisValue, const ArgList&);
+
+#ifdef QT_BUILD_SCRIPT_LIB
+ class NativeFuncWrapper
+ {
+ NativeFunction ptr;
+ public:
+ inline NativeFuncWrapper& operator=(NativeFunction func)
+ {
+ ptr = func;
+ return *this;
+ }
+ inline operator NativeFunction() const {return ptr;}
+ inline operator bool() const {return ptr;}
+
+ JSValue operator()(ExecState* exec, JSObject* jsobj, JSValue thisValue, const ArgList& argList) const;
+ };
+#endif
+
+#if defined(QT_BUILD_SCRIPT_LIB) && PLATFORM(SOLARIS)
+ struct
+#else
+ union
+#endif
+ CallData {
+ struct {
+#ifndef QT_BUILD_SCRIPT_LIB
+ NativeFunction function;
+#else
+ NativeFuncWrapper function;
+#endif
+ } 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h
new file mode 100644
index 0000000..097fb09
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ClassInfo.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ClassInfo_h
+#define ClassInfo_h
+
+#include "CallFrame.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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
new file mode 100644
index 0000000..d7fbce8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
@@ -0,0 +1,1376 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 "Collector.h"
+
+#include "ArgList.h"
+#include "CallFrame.h"
+#include "CollectorHeapIterator.h"
+#include "Interpreter.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "JSONObject.h"
+#include "JSString.h"
+#include "JSValue.h"
+#include "Nodes.h"
+#include "Tracing.h"
+#include <algorithm>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/HashCountedSet.h>
+#include <wtf/UnusedParam.h>
+#include <wtf/VMTags.h>
+
+#if PLATFORM(DARWIN)
+
+#include <mach/mach_init.h>
+#include <mach/mach_port.h>
+#include <mach/task.h>
+#include <mach/thread_act.h>
+#include <mach/vm_map.h>
+
+#elif PLATFORM(SYMBIAN)
+#include <e32std.h>
+#include <e32cmn.h>
+#include <unistd.h>
+
+#elif PLATFORM(WIN_OS)
+
+#include <windows.h>
+
+#elif PLATFORM(UNIX)
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#if defined(QT_LINUXBASE)
+#include <dlfcn.h>
+#endif
+
+#if defined(__UCLIBC__)
+// versions of uClibc 0.9.28 and below do not have
+// pthread_getattr_np or pthread_attr_getstack.
+#if __UCLIBC_MAJOR__ == 0 && \
+ (__UCLIBC_MINOR__ < 9 || \
+ (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ <= 30))
+#define UCLIBC_USE_PROC_SELF_MAPS 1
+#include <stdio_ext.h>
+extern int *__libc_stack_end;
+#endif
+#endif
+
+#if PLATFORM(SOLARIS)
+#include <thread.h>
+#else
+#include <pthread.h>
+#endif
+
+#if HAVE(PTHREAD_NP_H)
+#include <pthread_np.h>
+#endif
+
+#if PLATFORM(QNX)
+#include <fcntl.h>
+#include <sys/procfs.h>
+#include <stdio.h>
+#include <errno.h>
+#endif
+
+#endif
+
+#define DEBUG_COLLECTOR 0
+#define COLLECT_ON_EVERY_ALLOCATION 0
+
+using std::max;
+
+namespace JSC {
+
+// tunable parameters
+
+const size_t SPARE_EMPTY_BLOCKS = 2;
+const size_t GROWTH_FACTOR = 2;
+const size_t LOW_WATER_FACTOR = 4;
+const size_t ALLOCATIONS_PER_COLLECTION = 4000;
+// This value has to be a macro to be used in max() without introducing
+// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
+#define MIN_ARRAY_SIZE (static_cast<size_t>(14))
+
+#if PLATFORM(SYMBIAN)
+const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB
+static RHeap* userChunk = 0;
+#endif
+
+static void freeHeap(CollectorHeap*);
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+#if PLATFORM(DARWIN)
+typedef mach_port_t PlatformThread;
+#elif PLATFORM(WIN_OS)
+struct PlatformThread {
+ PlatformThread(DWORD _id, HANDLE _handle) : id(_id), handle(_handle) {}
+ DWORD id;
+ HANDLE handle;
+};
+#endif
+
+class Heap::Thread {
+public:
+ Thread(pthread_t pthread, const PlatformThread& platThread, void* base)
+ : posixThread(pthread)
+ , platformThread(platThread)
+ , stackBase(base)
+ {
+ }
+
+ Thread* next;
+ pthread_t posixThread;
+ PlatformThread platformThread;
+ void* stackBase;
+};
+
+#endif
+
+Heap::Heap(JSGlobalData* globalData)
+ : m_markListSet(0)
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ , m_registeredThreads(0)
+ , m_currentThreadRegistrar(0)
+#endif
+ , m_globalData(globalData)
+{
+ ASSERT(globalData);
+
+#if PLATFORM(SYMBIAN)
+ // Symbian OpenC supports mmap but currently not the MAP_ANON flag.
+ // Using fastMalloc() does not properly align blocks on 64k boundaries
+ // and previous implementation was flawed/incomplete.
+ // UserHeap::ChunkHeap allows allocation of continuous memory and specification
+ // of alignment value for (symbian) cells within that heap.
+ //
+ // Clarification and mapping of terminology:
+ // RHeap (created by UserHeap::ChunkHeap below) is continuos memory chunk,
+ // which can dynamically grow up to 8 MB,
+ // that holds all CollectorBlocks of this session (static).
+ // Each symbian cell within RHeap maps to a 64kb aligned CollectorBlock.
+ // JSCell objects are maintained as usual within CollectorBlocks.
+ if (!userChunk) {
+ userChunk = UserHeap::ChunkHeap(0, 0, MAX_NUM_BLOCKS * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
+ if (!userChunk)
+ CRASH();
+ }
+#endif // PLATFORM(SYMBIAN)
+
+ memset(&primaryHeap, 0, sizeof(CollectorHeap));
+ memset(&numberHeap, 0, sizeof(CollectorHeap));
+}
+
+Heap::~Heap()
+{
+ // The destroy function must already have been called, so assert this.
+ ASSERT(!m_globalData);
+}
+
+void Heap::destroy()
+{
+ JSLock lock(SilenceAssertionsOnly);
+
+ if (!m_globalData)
+ return;
+
+ // The global object is not GC protected at this point, so sweeping may delete it
+ // (and thus the global data) before other objects that may use the global data.
+ RefPtr<JSGlobalData> protect(m_globalData);
+
+ delete m_markListSet;
+ m_markListSet = 0;
+
+ sweep<PrimaryHeap>();
+ // No need to sweep number heap, because the JSNumber destructor doesn't do anything.
+
+ ASSERT(!primaryHeap.numLiveObjects);
+
+ freeHeap(&primaryHeap);
+ freeHeap(&numberHeap);
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ if (m_currentThreadRegistrar) {
+ int error = pthread_key_delete(m_currentThreadRegistrar);
+ ASSERT_UNUSED(error, !error);
+ }
+
+ MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
+ for (Heap::Thread* t = m_registeredThreads; t;) {
+ Heap::Thread* next = t->next;
+ delete t;
+ t = next;
+ }
+#endif
+
+ m_globalData = 0;
+}
+
+template <HeapType heapType>
+static NEVER_INLINE CollectorBlock* allocateBlock()
+{
+ // Disable the use of vm_map for the Qt build on Darwin, because when compiled on 10.4
+ // it crashes on 10.5
+#if PLATFORM(DARWIN) && !PLATFORM(QT)
+ vm_address_t address = 0;
+ // FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: <rdar://problem/6054788>.
+ vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
+#elif PLATFORM(SYMBIAN)
+ // Allocate a 64 kb aligned CollectorBlock
+ unsigned char* mask = reinterpret_cast<unsigned char*>(userChunk->Alloc(BLOCK_SIZE));
+ if (!mask)
+ CRASH();
+ uintptr_t address = reinterpret_cast<uintptr_t>(mask);
+
+ memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
+#elif PLATFORM(WIN_OS)
+ // windows virtual address granularity is naturally 64k
+ LPVOID address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+#elif HAVE(POSIX_MEMALIGN)
+ void* address;
+ posix_memalign(&address, BLOCK_SIZE, BLOCK_SIZE);
+ memset(address, 0, BLOCK_SIZE);
+#else
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+#error Need to initialize pagesize safely.
+#endif
+ static size_t pagesize = getpagesize();
+
+ size_t extra = 0;
+ if (BLOCK_SIZE > pagesize)
+ extra = BLOCK_SIZE - pagesize;
+
+ void* mmapResult = mmap(NULL, BLOCK_SIZE + extra, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ uintptr_t address = reinterpret_cast<uintptr_t>(mmapResult);
+
+ size_t adjust = 0;
+ if ((address & BLOCK_OFFSET_MASK) != 0)
+ adjust = BLOCK_SIZE - (address & BLOCK_OFFSET_MASK);
+
+ if (adjust > 0)
+ munmap(reinterpret_cast<char*>(address), adjust);
+
+ if (adjust < extra)
+ munmap(reinterpret_cast<char*>(address + adjust + BLOCK_SIZE), extra - adjust);
+
+ address += adjust;
+ memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
+#endif
+ reinterpret_cast<CollectorBlock*>(address)->type = heapType;
+ return reinterpret_cast<CollectorBlock*>(address);
+}
+
+static void freeBlock(CollectorBlock* block)
+{
+ // Disable the use of vm_deallocate for the Qt build on Darwin, because when compiled on 10.4
+ // it crashes on 10.5
+#if PLATFORM(DARWIN) && !PLATFORM(QT)
+ vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE);
+#elif PLATFORM(SYMBIAN)
+ userChunk->Free(reinterpret_cast<TAny*>(block));
+#elif PLATFORM(WIN_OS)
+ VirtualFree(block, 0, MEM_RELEASE);
+#elif HAVE(POSIX_MEMALIGN)
+ free(block);
+#else
+ munmap(reinterpret_cast<char*>(block), BLOCK_SIZE);
+#endif
+}
+
+static void freeHeap(CollectorHeap* heap)
+{
+ for (size_t i = 0; i < heap->usedBlocks; ++i)
+ if (heap->blocks[i])
+ freeBlock(heap->blocks[i]);
+ fastFree(heap->blocks);
+ memset(heap, 0, sizeof(CollectorHeap));
+}
+
+void Heap::recordExtraCost(size_t cost)
+{
+ // Our frequency of garbage collection tries to balance memory use against speed
+ // by collecting based on the number of newly created values. However, for values
+ // that hold on to a great deal of memory that's not in the form of other JS values,
+ // that is not good enough - in some cases a lot of those objects can pile up and
+ // use crazy amounts of memory without a GC happening. So we track these extra
+ // memory costs. Only unusually large objects are noted, and we only keep track
+ // of this extra cost until the next GC. In garbage collected languages, most values
+ // are either very short lived temporaries, or have extremely long lifetimes. So
+ // if a large value survives one garbage collection, there is not much point to
+ // collecting more frequently as long as it stays alive.
+ // NOTE: we target the primaryHeap unconditionally as JSNumber doesn't modify cost
+
+ primaryHeap.extraCost += cost;
+}
+
+template <HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
+{
+ typedef typename HeapConstants<heapType>::Block Block;
+ typedef typename HeapConstants<heapType>::Cell Cell;
+
+ CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
+ ASSERT(JSLock::lockCount() > 0);
+ ASSERT(JSLock::currentThreadIsHoldingLock());
+ ASSERT_UNUSED(s, s <= HeapConstants<heapType>::cellSize);
+
+ ASSERT(heap.operationInProgress == NoOperation);
+ ASSERT(heapType == PrimaryHeap || heap.extraCost == 0);
+ // FIXME: If another global variable access here doesn't hurt performance
+ // too much, we could CRASH() in NDEBUG builds, which could help ensure we
+ // don't spend any time debugging cases where we allocate inside an object's
+ // deallocation code.
+
+#if COLLECT_ON_EVERY_ALLOCATION
+ collect();
+#endif
+
+ size_t numLiveObjects = heap.numLiveObjects;
+ size_t usedBlocks = heap.usedBlocks;
+ size_t i = heap.firstBlockWithPossibleSpace;
+
+ // if we have a huge amount of extra cost, we'll try to collect even if we still have
+ // free cells left.
+ if (heapType == PrimaryHeap && heap.extraCost > ALLOCATIONS_PER_COLLECTION) {
+ size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect;
+ size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect;
+ const size_t newCost = numNewObjects + heap.extraCost;
+ if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect)
+ goto collect;
+ }
+
+ ASSERT(heap.operationInProgress == NoOperation);
+#ifndef NDEBUG
+ // FIXME: Consider doing this in NDEBUG builds too (see comment above).
+ heap.operationInProgress = Allocation;
+#endif
+
+scan:
+ Block* targetBlock;
+ size_t targetBlockUsedCells;
+ if (i != usedBlocks) {
+ targetBlock = reinterpret_cast<Block*>(heap.blocks[i]);
+ targetBlockUsedCells = targetBlock->usedCells;
+ ASSERT(targetBlockUsedCells <= HeapConstants<heapType>::cellsPerBlock);
+ while (targetBlockUsedCells == HeapConstants<heapType>::cellsPerBlock) {
+ if (++i == usedBlocks)
+ goto collect;
+ targetBlock = reinterpret_cast<Block*>(heap.blocks[i]);
+ targetBlockUsedCells = targetBlock->usedCells;
+ ASSERT(targetBlockUsedCells <= HeapConstants<heapType>::cellsPerBlock);
+ }
+ heap.firstBlockWithPossibleSpace = i;
+ } else {
+
+collect:
+ size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect;
+ size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect;
+ const size_t newCost = numNewObjects + heap.extraCost;
+
+ if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect) {
+#ifndef NDEBUG
+ heap.operationInProgress = NoOperation;
+#endif
+ bool collected = collect();
+#ifndef NDEBUG
+ heap.operationInProgress = Allocation;
+#endif
+ if (collected) {
+ numLiveObjects = heap.numLiveObjects;
+ usedBlocks = heap.usedBlocks;
+ i = heap.firstBlockWithPossibleSpace;
+ goto scan;
+ }
+ }
+
+ // didn't find a block, and GC didn't reclaim anything, need to allocate a new block
+ size_t numBlocks = heap.numBlocks;
+ if (usedBlocks == numBlocks) {
+ static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR;
+ if (numBlocks > maxNumBlocks)
+ CRASH();
+ numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
+ heap.numBlocks = numBlocks;
+ heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*)));
+ }
+
+ targetBlock = reinterpret_cast<Block*>(allocateBlock<heapType>());
+ targetBlock->freeList = targetBlock->cells;
+ targetBlock->heap = this;
+ targetBlockUsedCells = 0;
+ heap.blocks[usedBlocks] = reinterpret_cast<CollectorBlock*>(targetBlock);
+ heap.usedBlocks = usedBlocks + 1;
+ heap.firstBlockWithPossibleSpace = usedBlocks;
+ }
+
+ // find a free spot in the block and detach it from the free list
+ Cell* newCell = targetBlock->freeList;
+
+ // "next" field is a cell offset -- 0 means next cell, so a zeroed block is already initialized
+ targetBlock->freeList = (newCell + 1) + newCell->u.freeCell.next;
+
+ targetBlock->usedCells = static_cast<uint32_t>(targetBlockUsedCells + 1);
+ heap.numLiveObjects = numLiveObjects + 1;
+
+#ifndef NDEBUG
+ // FIXME: Consider doing this in NDEBUG builds too (see comment above).
+ heap.operationInProgress = NoOperation;
+#endif
+
+ return newCell;
+}
+
+void* Heap::allocate(size_t s)
+{
+ return heapAllocate<PrimaryHeap>(s);
+}
+
+void* Heap::allocateNumber(size_t s)
+{
+ return heapAllocate<NumberHeap>(s);
+}
+
+#if PLATFORM(WINCE)
+void* g_stackBase = 0;
+
+inline bool isPageWritable(void* page)
+{
+ MEMORY_BASIC_INFORMATION memoryInformation;
+ DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
+
+ // return false on error, including ptr outside memory
+ if (result != sizeof(memoryInformation))
+ return false;
+
+ DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
+ return protect == PAGE_READWRITE
+ || protect == PAGE_WRITECOPY
+ || protect == PAGE_EXECUTE_READWRITE
+ || protect == PAGE_EXECUTE_WRITECOPY;
+}
+
+static void* getStackBase(void* previousFrame)
+{
+ // find the address of this stack frame by taking the address of a local variable
+ bool isGrowingDownward;
+ void* thisFrame = (void*)(&isGrowingDownward);
+
+ isGrowingDownward = previousFrame < &thisFrame;
+ static DWORD pageSize = 0;
+ if (!pageSize) {
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ pageSize = systemInfo.dwPageSize;
+ }
+
+ // scan all of memory starting from this frame, and return the last writeable page found
+ register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1));
+ if (isGrowingDownward) {
+ while (currentPage > 0) {
+ // check for underflow
+ if (currentPage >= (char*)pageSize)
+ currentPage -= pageSize;
+ else
+ currentPage = 0;
+ if (!isPageWritable(currentPage))
+ return currentPage + pageSize;
+ }
+ return 0;
+ } else {
+ while (true) {
+ // guaranteed to complete because isPageWritable returns false at end of memory
+ currentPage += pageSize;
+ if (!isPageWritable(currentPage))
+ return currentPage;
+ }
+ }
+}
+#endif
+#if PLATFORM(HPUX)
+struct hpux_get_stack_base_data
+{
+ pthread_t thread;
+ _pthread_stack_info info;
+};
+
+static void *hpux_get_stack_base_internal(void *d)
+{
+ hpux_get_stack_base_data *data = static_cast<hpux_get_stack_base_data *>(d);
+
+ // _pthread_stack_info_np requires the target thread to be suspended
+ // in order to get information about it
+ pthread_suspend(data->thread);
+
+ // _pthread_stack_info_np returns an errno code in case of failure
+ // or zero on success
+ if (_pthread_stack_info_np(data->thread, &data->info)) {
+ // failed
+ return 0;
+ }
+
+ pthread_continue(data->thread);
+ return data;
+}
+
+static void *hpux_get_stack_base()
+{
+ hpux_get_stack_base_data data;
+ data.thread = pthread_self();
+
+ // We cannot get the stack information for the current thread
+ // So we start a new thread to get that information and return it to us
+ pthread_t other;
+ pthread_create(&other, 0, hpux_get_stack_base_internal, &data);
+
+ void *result;
+ pthread_join(other, &result);
+ if (result)
+ return data.info.stk_stack_base;
+ return 0;
+}
+#endif
+
+static inline void* currentThreadStackBase()
+{
+#if PLATFORM(DARWIN)
+ pthread_t thread = pthread_self();
+ return pthread_get_stackaddr_np(thread);
+#elif PLATFORM(WIN_OS) && PLATFORM(X86) && COMPILER(MSVC)
+ // offset 0x18 from the FS segment register gives a pointer to
+ // the thread information block for the current thread
+ NT_TIB* pTib;
+ __asm {
+ MOV EAX, FS:[18h]
+ MOV pTib, EAX
+ }
+ return static_cast<void*>(pTib->StackBase);
+#elif PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC)
+ PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
+ return reinterpret_cast<void*>(pTib->StackBase);
+#elif PLATFORM(WIN_OS) && PLATFORM(X86) && COMPILER(GCC)
+ // offset 0x18 from the FS segment register gives a pointer to
+ // the thread information block for the current thread
+ NT_TIB* pTib;
+ asm ( "movl %%fs:0x18, %0\n"
+ : "=r" (pTib)
+ );
+ return static_cast<void*>(pTib->StackBase);
+#elif PLATFORM(HPUX)
+ return hpux_get_stack_base();
+#elif PLATFORM(SOLARIS)
+ stack_t s;
+ thr_stksegment(&s);
+ return s.ss_sp;
+#elif PLATFORM(AIX)
+ pthread_t thread = pthread_self();
+ struct __pthrdsinfo threadinfo;
+ char regbuf[256];
+ int regbufsize = sizeof regbuf;
+
+ if (pthread_getthrds_np(&thread, PTHRDSINFO_QUERY_ALL,
+ &threadinfo, sizeof threadinfo,
+ &regbuf, &regbufsize) == 0)
+ return threadinfo.__pi_stackaddr;
+
+ return 0;
+#elif PLATFORM(OPENBSD)
+ pthread_t thread = pthread_self();
+ stack_t stack;
+ pthread_stackseg_np(thread, &stack);
+ return stack.ss_sp;
+#elif PLATFORM(SYMBIAN)
+ static void* stackBase = 0;
+ if (stackBase == 0) {
+ TThreadStackInfo info;
+ RThread thread;
+ thread.StackInfo(info);
+ stackBase = (void*)info.iBase;
+ }
+ return (void*)stackBase;
+#elif PLATFORM(UNIX)
+#ifdef UCLIBC_USE_PROC_SELF_MAPS
+ // Read /proc/self/maps and locate the line whose address
+ // range contains __libc_stack_end.
+ FILE *file = fopen("/proc/self/maps", "r");
+ if (!file)
+ return 0;
+ __fsetlocking(file, FSETLOCKING_BYCALLER);
+ char *line = NULL;
+ size_t lineLen = 0;
+ while (!feof_unlocked(file)) {
+ if (getdelim(&line, &lineLen, '\n', file) <= 0)
+ break;
+
+ long from;
+ long to;
+ if (sscanf (line, "%lx-%lx", &from, &to) != 2)
+ continue;
+ if (from <= (long)__libc_stack_end && (long)__libc_stack_end < to) {
+ fclose(file);
+ free(line);
+#ifdef _STACK_GROWS_UP
+ return (void *)from;
+#else
+ return (void *)to;
+#endif
+ }
+ }
+ fclose(file);
+ free(line);
+ return 0;
+#else
+ static void* stackBase = 0;
+ static size_t stackSize = 0;
+ static pthread_t stackThread;
+ pthread_t thread = pthread_self();
+ if (stackBase == 0 || thread != stackThread) {
+#if PLATFORM(QNX)
+ int fd;
+ struct _debug_thread_info tinfo;
+ memset(&tinfo, 0, sizeof(tinfo));
+ tinfo.tid = pthread_self();
+ fd = open("/proc/self", O_RDONLY);
+ if (fd == -1) {
+#ifndef NDEBUG
+ perror("Unable to open /proc/self:");
+#endif
+ return 0;
+ }
+ devctl(fd, DCMD_PROC_TIDSTATUS, &tinfo, sizeof(tinfo), NULL);
+ close(fd);
+ stackBase = (void*)tinfo.stkbase;
+ stackSize = tinfo.stksize;
+ ASSERT(stackBase);
+#else
+#if defined(QT_LINUXBASE)
+ // LinuxBase is missing pthread_getattr_np - resolve it once at runtime instead
+ // see http://bugs.linuxbase.org/show_bug.cgi?id=2364
+ typedef int (*GetAttrPtr)(pthread_t, pthread_attr_t *);
+ static int (*pthread_getattr_np_ptr)(pthread_t, pthread_attr_t *) = 0;
+ if (!pthread_getattr_np_ptr)
+ *(void **)&pthread_getattr_np_ptr = dlsym(RTLD_DEFAULT, "pthread_getattr_np");
+#endif
+ pthread_attr_t sattr;
+ pthread_attr_init(&sattr);
+#if HAVE(PTHREAD_NP_H) || PLATFORM(NETBSD)
+ // e.g. on FreeBSD 5.4, neundorf@kde.org
+ pthread_attr_get_np(thread, &sattr);
+#elif defined(QT_LINUXBASE)
+ if (pthread_getattr_np_ptr)
+ pthread_getattr_np_ptr(thread, &sattr);
+#else
+ // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
+ pthread_getattr_np(thread, &sattr);
+#endif
+ int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
+ (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
+ ASSERT(stackBase);
+ pthread_attr_destroy(&sattr);
+#endif
+ stackThread = thread;
+ }
+ return static_cast<char*>(stackBase) + stackSize;
+#endif
+#elif PLATFORM(WINCE)
+ if (g_stackBase)
+ return g_stackBase;
+ else {
+ int dummy;
+ return getStackBase(&dummy);
+ }
+#else
+#error Need a way to get the stack base on this platform
+#endif
+}
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+static inline PlatformThread getCurrentPlatformThread()
+{
+#if PLATFORM(DARWIN)
+ return pthread_mach_thread_np(pthread_self());
+#elif PLATFORM(WIN_OS)
+ HANDLE threadHandle = pthread_getw32threadhandle_np(pthread_self());
+ return PlatformThread(GetCurrentThreadId(), threadHandle);
+#endif
+}
+
+void Heap::makeUsableFromMultipleThreads()
+{
+ if (m_currentThreadRegistrar)
+ return;
+
+ int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
+ if (error)
+ CRASH();
+}
+
+void Heap::registerThread()
+{
+ if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
+ return;
+
+ pthread_setspecific(m_currentThreadRegistrar, this);
+ Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
+
+ MutexLocker lock(m_registeredThreadsMutex);
+
+ thread->next = m_registeredThreads;
+ m_registeredThreads = thread;
+}
+
+void Heap::unregisterThread(void* p)
+{
+ if (p)
+ static_cast<Heap*>(p)->unregisterThread();
+}
+
+void Heap::unregisterThread()
+{
+ pthread_t currentPosixThread = pthread_self();
+
+ MutexLocker lock(m_registeredThreadsMutex);
+
+ if (pthread_equal(currentPosixThread, m_registeredThreads->posixThread)) {
+ Thread* t = m_registeredThreads;
+ m_registeredThreads = m_registeredThreads->next;
+ delete t;
+ } else {
+ Heap::Thread* last = m_registeredThreads;
+ Heap::Thread* t;
+ for (t = m_registeredThreads->next; t; t = t->next) {
+ if (pthread_equal(t->posixThread, currentPosixThread)) {
+ last->next = t->next;
+ break;
+ }
+ last = t;
+ }
+ ASSERT(t); // If t is NULL, we never found ourselves in the list.
+ delete t;
+ }
+}
+
+#else // ENABLE(JSC_MULTIPLE_THREADS)
+
+void Heap::registerThread()
+{
+}
+
+#endif
+
+#define IS_POINTER_ALIGNED(p) (((intptr_t)(p) & (sizeof(char*) - 1)) == 0)
+
+// cell size needs to be a power of two for this to be valid
+#define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0)
+
+void Heap::markConservatively(void* start, void* end)
+{
+ if (start > end) {
+ void* tmp = start;
+ start = end;
+ end = tmp;
+ }
+
+ ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000);
+ ASSERT(IS_POINTER_ALIGNED(start));
+ ASSERT(IS_POINTER_ALIGNED(end));
+
+ char** p = static_cast<char**>(start);
+ char** e = static_cast<char**>(end);
+
+ size_t usedPrimaryBlocks = primaryHeap.usedBlocks;
+ size_t usedNumberBlocks = numberHeap.usedBlocks;
+ CollectorBlock** primaryBlocks = primaryHeap.blocks;
+ CollectorBlock** numberBlocks = numberHeap.blocks;
+
+ const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
+
+ while (p != e) {
+ char* x = *p++;
+ if (IS_HALF_CELL_ALIGNED(x) && x) {
+ uintptr_t xAsBits = reinterpret_cast<uintptr_t>(x);
+ xAsBits &= CELL_ALIGN_MASK;
+ uintptr_t offset = xAsBits & BLOCK_OFFSET_MASK;
+ CollectorBlock* blockAddr = reinterpret_cast<CollectorBlock*>(xAsBits - offset);
+ // Mark the the number heap, we can mark these Cells directly to avoid the virtual call cost
+ for (size_t block = 0; block < usedNumberBlocks; block++) {
+ if ((numberBlocks[block] == blockAddr) & (offset <= lastCellOffset)) {
+ Heap::markCell(reinterpret_cast<JSCell*>(xAsBits));
+ goto endMarkLoop;
+ }
+ }
+
+ // Mark the primary heap
+ for (size_t block = 0; block < usedPrimaryBlocks; block++) {
+ if ((primaryBlocks[block] == blockAddr) & (offset <= lastCellOffset)) {
+ if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree != 0) {
+ JSCell* imp = reinterpret_cast<JSCell*>(xAsBits);
+ if (!imp->marked())
+ imp->mark();
+ }
+ break;
+ }
+ }
+ endMarkLoop:
+ ;
+ }
+ }
+}
+
+void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal()
+{
+ void* dummy;
+ void* stackPointer = &dummy;
+ void* stackBase = currentThreadStackBase();
+ markConservatively(stackPointer, stackBase);
+}
+
+void Heap::markCurrentThreadConservatively()
+{
+ // setjmp forces volatile registers onto the stack
+ jmp_buf registers;
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4611)
+#endif
+ setjmp(registers);
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+ markCurrentThreadConservativelyInternal();
+}
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+static inline void suspendThread(const PlatformThread& platformThread)
+{
+#if PLATFORM(DARWIN)
+ thread_suspend(platformThread);
+#elif PLATFORM(WIN_OS)
+ SuspendThread(platformThread.handle);
+#else
+#error Need a way to suspend threads on this platform
+#endif
+}
+
+static inline void resumeThread(const PlatformThread& platformThread)
+{
+#if PLATFORM(DARWIN)
+ thread_resume(platformThread);
+#elif PLATFORM(WIN_OS)
+ ResumeThread(platformThread.handle);
+#else
+#error Need a way to resume threads on this platform
+#endif
+}
+
+typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
+
+#if PLATFORM(DARWIN)
+
+#if PLATFORM(X86)
+typedef i386_thread_state_t PlatformThreadRegisters;
+#elif PLATFORM(X86_64)
+typedef x86_thread_state64_t PlatformThreadRegisters;
+#elif PLATFORM(PPC)
+typedef ppc_thread_state_t PlatformThreadRegisters;
+#elif PLATFORM(PPC64)
+typedef ppc_thread_state64_t PlatformThreadRegisters;
+#elif PLATFORM(ARM)
+typedef arm_thread_state_t PlatformThreadRegisters;
+#else
+#error Unknown Architecture
+#endif
+
+#elif PLATFORM(WIN_OS)&& PLATFORM(X86)
+typedef CONTEXT PlatformThreadRegisters;
+#else
+#error Need a thread register struct for this platform
+#endif
+
+static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
+{
+#if PLATFORM(DARWIN)
+
+#if PLATFORM(X86)
+ unsigned user_count = sizeof(regs)/sizeof(int);
+ thread_state_flavor_t flavor = i386_THREAD_STATE;
+#elif PLATFORM(X86_64)
+ unsigned user_count = x86_THREAD_STATE64_COUNT;
+ thread_state_flavor_t flavor = x86_THREAD_STATE64;
+#elif PLATFORM(PPC)
+ unsigned user_count = PPC_THREAD_STATE_COUNT;
+ thread_state_flavor_t flavor = PPC_THREAD_STATE;
+#elif PLATFORM(PPC64)
+ unsigned user_count = PPC_THREAD_STATE64_COUNT;
+ thread_state_flavor_t flavor = PPC_THREAD_STATE64;
+#elif PLATFORM(ARM)
+ unsigned user_count = ARM_THREAD_STATE_COUNT;
+ thread_state_flavor_t flavor = ARM_THREAD_STATE;
+#else
+#error Unknown Architecture
+#endif
+
+ kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)&regs, &user_count);
+ if (result != KERN_SUCCESS) {
+ WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION,
+ "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result);
+ CRASH();
+ }
+ return user_count * sizeof(usword_t);
+// end PLATFORM(DARWIN)
+
+#elif PLATFORM(WIN_OS) && PLATFORM(X86)
+ regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS;
+ GetThreadContext(platformThread.handle, &regs);
+ return sizeof(CONTEXT);
+#else
+#error Need a way to get thread registers on this platform
+#endif
+}
+
+static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
+{
+#if PLATFORM(DARWIN)
+
+#if __DARWIN_UNIX03
+
+#if PLATFORM(X86)
+ return reinterpret_cast<void*>(regs.__esp);
+#elif PLATFORM(X86_64)
+ return reinterpret_cast<void*>(regs.__rsp);
+#elif PLATFORM(PPC) || PLATFORM(PPC64)
+ return reinterpret_cast<void*>(regs.__r1);
+#elif PLATFORM(ARM)
+ return reinterpret_cast<void*>(regs.__sp);
+#else
+#error Unknown Architecture
+#endif
+
+#else // !__DARWIN_UNIX03
+
+#if PLATFORM(X86)
+ return reinterpret_cast<void*>(regs.esp);
+#elif PLATFORM(X86_64)
+ return reinterpret_cast<void*>(regs.rsp);
+#elif (PLATFORM(PPC) || PLATFORM(PPC64))
+ return reinterpret_cast<void*>(regs.r1);
+#else
+#error Unknown Architecture
+#endif
+
+#endif // __DARWIN_UNIX03
+
+// end PLATFORM(DARWIN)
+#elif PLATFORM(X86) && PLATFORM(WIN_OS)
+ return reinterpret_cast<void*>((uintptr_t) regs.Esp);
+#else
+#error Need a way to get the stack pointer for another thread on this platform
+#endif
+}
+
+void Heap::markOtherThreadConservatively(Thread* thread)
+{
+ suspendThread(thread->platformThread);
+
+ PlatformThreadRegisters regs;
+ size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
+
+ // mark the thread's registers
+ markConservatively(static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
+
+ void* stackPointer = otherThreadStackPointer(regs);
+ markConservatively(stackPointer, thread->stackBase);
+
+ resumeThread(thread->platformThread);
+}
+
+#endif
+
+void Heap::markStackObjectsConservatively()
+{
+ markCurrentThreadConservatively();
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+ if (m_currentThreadRegistrar) {
+
+ MutexLocker lock(m_registeredThreadsMutex);
+
+#ifndef NDEBUG
+ // Forbid malloc during the mark phase. Marking a thread suspends it, so
+ // a malloc inside mark() would risk a deadlock with a thread that had been
+ // suspended while holding the malloc lock.
+ fastMallocForbid();
+#endif
+ // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
+ // and since this is a shared heap, they are real locks.
+ for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
+ if (!pthread_equal(thread->posixThread, pthread_self()))
+ markOtherThreadConservatively(thread);
+ }
+#ifndef NDEBUG
+ fastMallocAllow();
+#endif
+ }
+#endif
+}
+
+void Heap::setGCProtectNeedsLocking()
+{
+ // Most clients do not need to call this, with the notable exception of WebCore.
+ // Clients that use shared heap have JSLock protection, while others are supposed
+ // to do explicit locking. WebCore violates this contract in Database code,
+ // which calls gcUnprotect from a secondary thread.
+ if (!m_protectedValuesMutex)
+ m_protectedValuesMutex.set(new Mutex);
+}
+
+void Heap::protect(JSValue k)
+{
+ ASSERT(k);
+ ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
+
+ if (!k.isCell())
+ return;
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->lock();
+
+ m_protectedValues.add(k.asCell());
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->unlock();
+}
+
+void Heap::unprotect(JSValue k)
+{
+ ASSERT(k);
+ ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
+
+ if (!k.isCell())
+ return;
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->lock();
+
+ m_protectedValues.remove(k.asCell());
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->unlock();
+}
+
+Heap* Heap::heap(JSValue v)
+{
+ if (!v.isCell())
+ return 0;
+ return Heap::cellBlock(v.asCell())->heap;
+}
+
+void Heap::markProtectedObjects()
+{
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->lock();
+
+ ProtectCountSet::iterator end = m_protectedValues.end();
+ for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
+ JSCell* val = it->first;
+ if (!val->marked())
+ val->mark();
+ }
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->unlock();
+}
+
+template <HeapType heapType> size_t Heap::sweep()
+{
+ typedef typename HeapConstants<heapType>::Block Block;
+ typedef typename HeapConstants<heapType>::Cell Cell;
+
+ // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
+ CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
+
+ size_t emptyBlocks = 0;
+ size_t numLiveObjects = heap.numLiveObjects;
+
+ for (size_t block = 0; block < heap.usedBlocks; block++) {
+ Block* curBlock = reinterpret_cast<Block*>(heap.blocks[block]);
+
+ size_t usedCells = curBlock->usedCells;
+ Cell* freeList = curBlock->freeList;
+
+ if (usedCells == HeapConstants<heapType>::cellsPerBlock) {
+ // special case with a block where all cells are used -- testing indicates this happens often
+ for (size_t i = 0; i < HeapConstants<heapType>::cellsPerBlock; i++) {
+ if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
+ Cell* cell = curBlock->cells + i;
+
+ if (heapType != NumberHeap) {
+ JSCell* imp = reinterpret_cast<JSCell*>(cell);
+ // special case for allocated but uninitialized object
+ // (We don't need this check earlier because nothing prior this point
+ // assumes the object has a valid vptr.)
+ if (cell->u.freeCell.zeroIfFree == 0)
+ continue;
+
+ imp->~JSCell();
+ }
+
+ --usedCells;
+ --numLiveObjects;
+
+ // put cell on the free list
+ cell->u.freeCell.zeroIfFree = 0;
+ cell->u.freeCell.next = freeList - (cell + 1);
+ freeList = cell;
+ }
+ }
+ } else {
+ size_t minimumCellsToProcess = usedCells;
+ for (size_t i = 0; (i < minimumCellsToProcess) & (i < HeapConstants<heapType>::cellsPerBlock); i++) {
+ Cell* cell = curBlock->cells + i;
+ if (cell->u.freeCell.zeroIfFree == 0) {
+ ++minimumCellsToProcess;
+ } else {
+ if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
+ if (heapType != NumberHeap) {
+ JSCell* imp = reinterpret_cast<JSCell*>(cell);
+ imp->~JSCell();
+ }
+ --usedCells;
+ --numLiveObjects;
+
+ // put cell on the free list
+ cell->u.freeCell.zeroIfFree = 0;
+ cell->u.freeCell.next = freeList - (cell + 1);
+ freeList = cell;
+ }
+ }
+ }
+ }
+
+ curBlock->usedCells = static_cast<uint32_t>(usedCells);
+ curBlock->freeList = freeList;
+ curBlock->marked.clearAll();
+
+ if (usedCells == 0) {
+ emptyBlocks++;
+ if (emptyBlocks > SPARE_EMPTY_BLOCKS) {
+#if !DEBUG_COLLECTOR
+ freeBlock(reinterpret_cast<CollectorBlock*>(curBlock));
+#endif
+ // swap with the last block so we compact as we go
+ heap.blocks[block] = heap.blocks[heap.usedBlocks - 1];
+ heap.usedBlocks--;
+ block--; // Don't move forward a step in this case
+
+ if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) {
+ heap.numBlocks = heap.numBlocks / GROWTH_FACTOR;
+ heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*)));
+ }
+ }
+ }
+ }
+
+ if (heap.numLiveObjects != numLiveObjects)
+ heap.firstBlockWithPossibleSpace = 0;
+
+ heap.numLiveObjects = numLiveObjects;
+ heap.numLiveObjectsAtLastCollect = numLiveObjects;
+ heap.extraCost = 0;
+ return numLiveObjects;
+}
+
+bool Heap::collect()
+{
+#ifndef NDEBUG
+ if (m_globalData->isSharedInstance) {
+ ASSERT(JSLock::lockCount() > 0);
+ ASSERT(JSLock::currentThreadIsHoldingLock());
+ }
+#endif
+
+ ASSERT((primaryHeap.operationInProgress == NoOperation) | (numberHeap.operationInProgress == NoOperation));
+ if ((primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation))
+ CRASH();
+
+ JAVASCRIPTCORE_GC_BEGIN();
+ primaryHeap.operationInProgress = Collection;
+ numberHeap.operationInProgress = Collection;
+
+ // MARK: first mark all referenced objects recursively starting out from the set of root objects
+
+ markStackObjectsConservatively();
+ markProtectedObjects();
+#if QT_BUILD_SCRIPT_LIB
+ if (m_globalData->clientData)
+ m_globalData->clientData->mark();
+#endif
+ if (m_markListSet && m_markListSet->size())
+ MarkedArgumentBuffer::markLists(*m_markListSet);
+ if (m_globalData->exception && !m_globalData->exception.marked())
+ m_globalData->exception.mark();
+ m_globalData->interpreter->registerFile().markCallFrames(this);
+ m_globalData->smallStrings.mark();
+ if (m_globalData->scopeNodeBeingReparsed)
+ m_globalData->scopeNodeBeingReparsed->mark();
+ if (m_globalData->firstStringifierToMark)
+ JSONObject::markStringifiers(m_globalData->firstStringifierToMark);
+
+ JAVASCRIPTCORE_GC_MARKED();
+
+ size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
+ size_t numLiveObjects = sweep<PrimaryHeap>();
+ numLiveObjects += sweep<NumberHeap>();
+
+ primaryHeap.operationInProgress = NoOperation;
+ numberHeap.operationInProgress = NoOperation;
+ JAVASCRIPTCORE_GC_END(originalLiveObjects, numLiveObjects);
+
+ return numLiveObjects < originalLiveObjects;
+}
+
+size_t Heap::objectCount()
+{
+ return primaryHeap.numLiveObjects + numberHeap.numLiveObjects - m_globalData->smallStrings.count();
+}
+
+template <HeapType heapType>
+static void addToStatistics(Heap::Statistics& statistics, const CollectorHeap& heap)
+{
+ typedef HeapConstants<heapType> HC;
+ for (size_t i = 0; i < heap.usedBlocks; ++i) {
+ if (heap.blocks[i]) {
+ statistics.size += BLOCK_SIZE;
+ statistics.free += (HC::cellsPerBlock - heap.blocks[i]->usedCells) * HC::cellSize;
+ }
+ }
+}
+
+Heap::Statistics Heap::statistics() const
+{
+ Statistics statistics = { 0, 0 };
+ JSC::addToStatistics<PrimaryHeap>(statistics, primaryHeap);
+ JSC::addToStatistics<NumberHeap>(statistics, numberHeap);
+ return statistics;
+}
+
+size_t Heap::globalObjectCount()
+{
+ size_t count = 0;
+ if (JSGlobalObject* head = m_globalData->head) {
+ JSGlobalObject* o = head;
+ do {
+ ++count;
+ o = o->next();
+ } while (o != head);
+ }
+ return count;
+}
+
+size_t Heap::protectedGlobalObjectCount()
+{
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->lock();
+
+ size_t count = 0;
+ if (JSGlobalObject* head = m_globalData->head) {
+ JSGlobalObject* o = head;
+ do {
+ if (m_protectedValues.contains(o))
+ ++count;
+ o = o->next();
+ } while (o != head);
+ }
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->unlock();
+
+ return count;
+}
+
+size_t Heap::protectedObjectCount()
+{
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->lock();
+
+ size_t result = m_protectedValues.size();
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->unlock();
+
+ return result;
+}
+
+static const char* typeName(JSCell* cell)
+{
+ if (cell->isString())
+ return "string";
+ if (cell->isNumber())
+ return "number";
+ if (cell->isGetterSetter())
+ return "gettersetter";
+ ASSERT(cell->isObject());
+ const ClassInfo* info = static_cast<JSObject*>(cell)->classInfo();
+ return info ? info->className : "Object";
+}
+
+HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
+{
+ HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->lock();
+
+ ProtectCountSet::iterator end = m_protectedValues.end();
+ for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
+ counts->add(typeName(it->first));
+
+ if (m_protectedValuesMutex)
+ m_protectedValuesMutex->unlock();
+
+ return counts;
+}
+
+bool Heap::isBusy()
+{
+ return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation);
+}
+
+Heap::iterator Heap::primaryHeapBegin()
+{
+ return iterator(primaryHeap.blocks, primaryHeap.blocks + primaryHeap.usedBlocks);
+}
+
+Heap::iterator Heap::primaryHeapEnd()
+{
+ return iterator(primaryHeap.blocks + primaryHeap.usedBlocks, primaryHeap.blocks + primaryHeap.usedBlocks);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
new file mode 100644
index 0000000..852ac59
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * 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 Collector_h
+#define Collector_h
+
+#include <stddef.h>
+#include <string.h>
+#include <wtf/HashCountedSet.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/Threading.h>
+
+// This is supremely lame that we require pthreads to build on windows.
+#if ENABLE(JSC_MULTIPLE_THREADS)
+#include <pthread.h>
+#endif
+
+#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell)
+
+namespace JSC {
+
+ class MarkedArgumentBuffer;
+ class CollectorBlock;
+ class JSCell;
+ class JSGlobalData;
+ class JSValue;
+
+ enum OperationInProgress { NoOperation, Allocation, Collection };
+ enum HeapType { PrimaryHeap, NumberHeap };
+
+ template <HeapType> class CollectorHeapIterator;
+
+ struct CollectorHeap {
+ CollectorBlock** blocks;
+ size_t numBlocks;
+ size_t usedBlocks;
+ size_t firstBlockWithPossibleSpace;
+
+ size_t numLiveObjects;
+ size_t numLiveObjectsAtLastCollect;
+ size_t extraCost;
+
+ OperationInProgress operationInProgress;
+ };
+
+ class Heap : public Noncopyable {
+ public:
+ class Thread;
+ typedef CollectorHeapIterator<PrimaryHeap> iterator;
+
+ void destroy();
+
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ // We can inline these functions because everything is compiled as
+ // one file, so the heapAllocate template definitions are available.
+ // However, allocateNumber is used via jsNumberCell outside JavaScriptCore.
+ // Thus allocateNumber needs to provide a non-inline version too.
+ void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
+ void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
+#endif
+ void* allocateNumber(size_t);
+ void* allocate(size_t);
+
+ bool collect();
+ bool isBusy(); // true if an allocation or collection is in progress
+
+ static const size_t minExtraCostSize = 256;
+
+ void reportExtraMemoryCost(size_t cost);
+
+ size_t objectCount();
+ struct Statistics {
+ size_t size;
+ size_t free;
+ };
+ Statistics statistics() const;
+
+ void setGCProtectNeedsLocking();
+ void protect(JSValue);
+ void unprotect(JSValue);
+
+ static Heap* heap(JSValue); // 0 for immediate values
+
+ size_t globalObjectCount();
+ size_t protectedObjectCount();
+ size_t protectedGlobalObjectCount();
+ HashCountedSet<const char*>* protectedObjectTypeCounts();
+
+ void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
+
+ static bool isCellMarked(const JSCell*);
+ static void markCell(JSCell*);
+
+ void markConservatively(void* start, void* end);
+
+ HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
+
+ JSGlobalData* globalData() const { return m_globalData; }
+ static bool isNumber(JSCell*);
+
+ // Iterators for the object heap.
+ iterator primaryHeapBegin();
+ iterator primaryHeapEnd();
+
+ private:
+ template <HeapType heapType> void* heapAllocate(size_t);
+ template <HeapType heapType> size_t sweep();
+ static CollectorBlock* cellBlock(const JSCell*);
+ static size_t cellOffset(const JSCell*);
+
+ friend class JSGlobalData;
+ Heap(JSGlobalData*);
+ ~Heap();
+
+ void recordExtraCost(size_t);
+ void markProtectedObjects();
+ void markCurrentThreadConservatively();
+ void markCurrentThreadConservativelyInternal();
+ void markOtherThreadConservatively(Thread*);
+ void markStackObjectsConservatively();
+
+ typedef HashCountedSet<JSCell*> ProtectCountSet;
+
+ CollectorHeap primaryHeap;
+ CollectorHeap numberHeap;
+
+ OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
+ ProtectCountSet m_protectedValues;
+
+ HashSet<MarkedArgumentBuffer*>* m_markListSet;
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ void makeUsableFromMultipleThreads();
+
+ static void unregisterThread(void*);
+ void unregisterThread();
+
+ Mutex m_registeredThreadsMutex;
+ Thread* m_registeredThreads;
+ pthread_key_t m_currentThreadRegistrar;
+#endif
+
+ JSGlobalData* m_globalData;
+ };
+
+ // tunable parameters
+ template<size_t bytesPerWord> struct CellSize;
+
+ // cell size needs to be a power of two for certain optimizations in collector.cpp
+ template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; // 32-bit
+ template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; // 64-bit
+ const size_t BLOCK_SIZE = 16 * 4096; // 64k
+
+ // derived constants
+ const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
+ const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
+ const size_t MINIMUM_CELL_SIZE = CellSize<sizeof(void*)>::m_value;
+ const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
+ const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
+ const size_t SMALL_CELL_SIZE = CELL_SIZE / 2;
+ const size_t CELL_MASK = CELL_SIZE - 1;
+ const size_t CELL_ALIGN_MASK = ~CELL_MASK;
+ const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2);
+ const size_t SMALL_CELLS_PER_BLOCK = 2 * CELLS_PER_BLOCK;
+ const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8;
+ const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
+
+ struct CollectorBitmap {
+ uint32_t bits[BITMAP_WORDS];
+ bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); }
+ void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); }
+ void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); }
+ void clearAll() { memset(bits, 0, sizeof(bits)); }
+ };
+
+ struct CollectorCell {
+ union {
+ double memory[CELL_ARRAY_LENGTH];
+ struct {
+ void* zeroIfFree;
+ ptrdiff_t next;
+ } freeCell;
+ } u;
+ };
+
+ struct SmallCollectorCell {
+ union {
+ double memory[CELL_ARRAY_LENGTH / 2];
+ struct {
+ void* zeroIfFree;
+ ptrdiff_t next;
+ } freeCell;
+ } u;
+ };
+
+ class CollectorBlock {
+ public:
+ CollectorCell cells[CELLS_PER_BLOCK];
+ uint32_t usedCells;
+ CollectorCell* freeList;
+ CollectorBitmap marked;
+ Heap* heap;
+ HeapType type;
+ };
+
+ class SmallCellCollectorBlock {
+ public:
+ SmallCollectorCell cells[SMALL_CELLS_PER_BLOCK];
+ uint32_t usedCells;
+ SmallCollectorCell* freeList;
+ CollectorBitmap marked;
+ Heap* heap;
+ HeapType type;
+ };
+
+ template <HeapType heapType> struct HeapConstants;
+
+ template <> struct HeapConstants<PrimaryHeap> {
+ static const size_t cellSize = CELL_SIZE;
+ static const size_t cellsPerBlock = CELLS_PER_BLOCK;
+ static const size_t bitmapShift = 0;
+ typedef CollectorCell Cell;
+ typedef CollectorBlock Block;
+ };
+
+ template <> struct HeapConstants<NumberHeap> {
+ static const size_t cellSize = SMALL_CELL_SIZE;
+ static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
+ static const size_t bitmapShift = 1;
+ typedef SmallCollectorCell Cell;
+ typedef SmallCellCollectorBlock Block;
+ };
+
+ inline CollectorBlock* Heap::cellBlock(const JSCell* cell)
+ {
+ return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
+ }
+
+ inline bool Heap::isNumber(JSCell* cell)
+ {
+ return Heap::cellBlock(cell)->type == NumberHeap;
+ }
+
+ inline size_t Heap::cellOffset(const JSCell* cell)
+ {
+ return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
+ }
+
+ inline bool Heap::isCellMarked(const JSCell* cell)
+ {
+ return cellBlock(cell)->marked.get(cellOffset(cell));
+ }
+
+ inline void Heap::markCell(JSCell* cell)
+ {
+ cellBlock(cell)->marked.set(cellOffset(cell));
+ }
+
+ inline void Heap::reportExtraMemoryCost(size_t cost)
+ {
+ if (cost > minExtraCostSize)
+ recordExtraCost(cost / (CELL_SIZE * 2));
+ }
+
+} // namespace JSC
+
+#endif /* Collector_h */
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h
new file mode 100644
index 0000000..e38a852
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * 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"
+
+#ifndef CollectorHeapIterator_h
+#define CollectorHeapIterator_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
+
+#endif // CollectorHeapIterator_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.cpp
new file mode 100644
index 0000000..3837817
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 {
+
+static const char* const nullCString = 0;
+
+#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
+
+CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
+ : nullIdentifier(globalData, nullCString)
+ , emptyIdentifier(globalData, "")
+ , underscoreProto(globalData, "__proto__")
+ , thisIdentifier(globalData, "this")
+ JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
+{
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h
new file mode 100644
index 0000000..7b275bd
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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>
+
+// MarkedArgumentBuffer 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(toISOString) \
+ macro(toJSON) \
+ macro(toLocaleString) \
+ macro(toPrecision) \
+ macro(toString) \
+ macro(UTC) \
+ macro(valueOf) \
+ macro(displayName)
+
+namespace JSC {
+
+ class CommonIdentifiers : public Noncopyable {
+ private:
+ CommonIdentifiers(JSGlobalData*);
+ friend class JSGlobalData;
+
+ public:
+ const Identifier nullIdentifier;
+ const Identifier emptyIdentifier;
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp
new file mode 100644
index 0000000..04c9a2e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2007 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 "Completion.h"
+
+#include "CallFrame.h"
+#include "JSGlobalObject.h"
+#include "JSLock.h"
+#include "Interpreter.h"
+#include "Parser.h"
+#include "Debugger.h"
+#include <stdio.h>
+
+#ifdef QT_BUILD_SCRIPT_LIB
+#include "DebuggerCallFrame.h"
+#include "SourcePoolQt.h"
+#endif
+
+#if !PLATFORM(WIN_OS)
+#include <unistd.h>
+#endif
+
+namespace JSC {
+
+Completion checkSyntax(ExecState* exec, const SourceCode& source)
+{
+ JSLock lock(exec);
+
+ int errLine;
+ UString errMsg;
+
+ RefPtr<ProgramNode> progNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
+ if (!progNode)
+ return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
+ return Completion(Normal);
+}
+
+Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
+{
+ JSLock lock(exec);
+
+ intptr_t sourceId = source.provider()->asID();
+ int errLine;
+ UString errMsg;
+ RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
+
+ if (!programNode) {
+ JSValue error = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, source.provider()->url());
+ return Completion(Throw, error);
+ }
+
+ JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
+
+ JSValue exception;
+ JSValue result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
+
+ if (exception) {
+ if (exception.isObject() && asObject(exception)->isWatchdogException())
+ return Completion(Interrupted, exception);
+ return Completion(Throw, exception);
+ }
+
+ return Completion(Normal, result);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.h
new file mode 100644
index 0000000..41c9a64
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * 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.
+ *
+ */
+
+#ifndef Completion_h
+#define Completion_h
+
+#include "JSValue.h"
+
+namespace JSC {
+
+ class ExecState;
+ class ScopeChain;
+ class SourceCode;
+
+ enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted };
+
+ /*
+ * Completion objects are used to convey the return status and value
+ * from functions.
+ */
+ class Completion {
+ public:
+ Completion(ComplType type = Normal, JSValue value = JSValue())
+ : m_type(type)
+ , m_value(value)
+ {
+ }
+
+ ComplType complType() const { return m_type; }
+ JSValue value() const { return m_value; }
+ void setValue(JSValue v) { m_value = v; }
+ bool isValueCompletion() const { return m_value; }
+
+ private:
+ ComplType m_type;
+ JSValue m_value;
+ };
+
+ Completion checkSyntax(ExecState*, const SourceCode&);
+ Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValue thisValue = JSValue());
+
+} // namespace JSC
+
+#endif // Completion_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp
new file mode 100644
index 0000000..3dfc918
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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"
+
+
+#ifdef QT_BUILD_SCRIPT_LIB
+#include "Debugger.h"
+#include "DebuggerCallFrame.h"
+#include "JSGlobalObject.h"
+#endif
+
+namespace JSC {
+
+#ifdef QT_BUILD_SCRIPT_LIB
+JSObject* JSC::NativeConstrWrapper::operator() (ExecState* exec, JSObject* jsobj, const ArgList& argList) const
+{
+ Debugger* debugger = exec->lexicalGlobalObject()->debugger();
+ if (debugger)
+ debugger->callEvent(DebuggerCallFrame(exec), -1, -1);
+
+ JSObject* returnValue = ptr(exec, jsobj, argList);
+
+ if ((debugger) && (callDebuggerFunctionExit))
+ debugger->functionExit(JSValue(returnValue), -1);
+
+ return returnValue;
+}
+#endif
+
+JSObject* construct(ExecState* exec, JSValue callee, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+{
+ if (constructType == ConstructTypeHost)
+ return constructData.native.function(exec, asObject(callee), args);
+ ASSERT(constructType == ConstructTypeJS);
+ // FIXME: Can this be done more efficiently using the constructData?
+ return asFunction(callee)->construct(exec, args);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h
new file mode 100644
index 0000000..477399c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.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 ConstructData_h
+#define ConstructData_h
+
+namespace JSC {
+
+ class ArgList;
+ class ExecState;
+ class FunctionBodyNode;
+ class JSObject;
+ class JSValue;
+ class ScopeChainNode;
+
+ enum ConstructType {
+ ConstructTypeNone,
+ ConstructTypeHost,
+ ConstructTypeJS
+ };
+
+ typedef JSObject* (*NativeConstructor)(ExecState*, JSObject*, const ArgList&);
+
+#ifdef QT_BUILD_SCRIPT_LIB
+ class NativeConstrWrapper
+ {
+ NativeConstructor ptr;
+ //Hack. If this variable is true and if debugger is attached at the end of
+ //operator() execution functionExit event will be created (in most cases it will be default)
+ //This variable was created because of FunctionWrapper::proxyCall method that change result
+ //on fly. Event shuld be created with original value so the method should call it itself.
+ bool callDebuggerFunctionExit;
+ public:
+ inline NativeConstrWrapper& operator=(NativeConstructor func)
+ {
+ callDebuggerFunctionExit = true;
+ ptr = func;
+ return *this;
+ }
+ inline operator NativeConstructor() const {return ptr;}
+ inline operator bool() const {return ptr;}
+
+ inline void doNotCallDebuggerFunctionExit() {callDebuggerFunctionExit = false;}
+ JSObject* operator()(ExecState*, JSObject*, const ArgList&) const;
+ };
+#endif
+
+#if defined(QT_BUILD_SCRIPT_LIB) && PLATFORM(SOLARIS)
+ struct
+#else
+ union
+#endif
+ ConstructData {
+ struct {
+#ifndef QT_BUILD_SCRIPT_LIB
+ NativeConstructor function;
+#else
+ NativeConstrWrapper function;
+#endif
+ } 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp
new file mode 100644
index 0000000..6d7d934
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+#include "config.h"
+#include "DateConstructor.h"
+
+#include "DateConversion.h"
+#include "DateInstance.h"
+#include "DatePrototype.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+#include <math.h>
+#include <time.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+
+#if PLATFORM(WINCE) && !PLATFORM(QT)
+extern "C" time_t time(time_t* timer); //provided by libce
+#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 {
+
+// TODO: MakeTime (15.9.11.1) etc. ?
+
+ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
+
+static JSValue JSC_HOST_CALL dateParse(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateNow(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateUTC(ExecState*, JSObject*, JSValue, const ArgList&);
+
+DateConstructor::DateConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype)
+ : InternalFunction(&exec->globalData(), structure, Identifier(exec, datePrototype->classInfo()->className))
+{
+ putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
+
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(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(0).isObject(&DateInstance::info))
+ value = asDateInstance(args.at(0))->internalNumber();
+ else {
+ JSValue primitive = args.at(0).toPrimitive(exec);
+ if (primitive.isString())
+ value = parseDate(primitive.getString());
+ else
+ value = primitive.toNumber(exec);
+ }
+ } else {
+ if (isnan(args.at(0).toNumber(exec))
+ || isnan(args.at(1).toNumber(exec))
+ || (numArgs >= 3 && isnan(args.at(2).toNumber(exec)))
+ || (numArgs >= 4 && isnan(args.at(3).toNumber(exec)))
+ || (numArgs >= 5 && isnan(args.at(4).toNumber(exec)))
+ || (numArgs >= 6 && isnan(args.at(5).toNumber(exec)))
+ || (numArgs >= 7 && isnan(args.at(6).toNumber(exec))))
+ value = NaN;
+ else {
+ GregorianDateTime t;
+ int year = args.at(0).toInt32(exec);
+ t.year = (year >= 0 && year <= 99) ? year : year - 1900;
+ t.month = args.at(1).toInt32(exec);
+ t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1;
+ t.hour = args.at(3).toInt32(exec);
+ t.minute = args.at(4).toInt32(exec);
+ t.second = args.at(5).toInt32(exec);
+ t.isDST = -1;
+ double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
+ value = gregorianDateTimeToMS(t, ms, false);
+ }
+ }
+
+ 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 JSC_HOST_CALL 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 JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, parseDate(args.at(0).toString(exec)));
+}
+
+static JSValue JSC_HOST_CALL dateNow(ExecState* exec, JSObject*, JSValue, const ArgList&)
+{
+ return jsNumber(exec, getCurrentUTCTime());
+}
+
+static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ int n = args.size();
+ if (isnan(args.at(0).toNumber(exec))
+ || isnan(args.at(1).toNumber(exec))
+ || (n >= 3 && isnan(args.at(2).toNumber(exec)))
+ || (n >= 4 && isnan(args.at(3).toNumber(exec)))
+ || (n >= 5 && isnan(args.at(4).toNumber(exec)))
+ || (n >= 6 && isnan(args.at(5).toNumber(exec)))
+ || (n >= 7 && isnan(args.at(6).toNumber(exec))))
+ return jsNaN(exec);
+
+ GregorianDateTime t;
+ int year = args.at(0).toInt32(exec);
+ t.year = (year >= 0 && year <= 99) ? year : year - 1900;
+ t.month = args.at(1).toInt32(exec);
+ t.monthDay = (n >= 3) ? args.at(2).toInt32(exec) : 1;
+ t.hour = args.at(3).toInt32(exec);
+ t.minute = args.at(4).toInt32(exec);
+ t.second = args.at(5).toInt32(exec);
+ double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
+ return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h
new file mode 100644
index 0000000..dcef3cc
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DateConstructor_h
+#define DateConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class DatePrototype;
+
+ class DateConstructor : public InternalFunction {
+ public:
+ DateConstructor(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure, DatePrototype*);
+
+ private:
+ virtual ConstructType getConstructData(ConstructData&);
+ virtual CallType getCallData(CallData&);
+ };
+
+ JSObject* constructDate(ExecState*, const ArgList&);
+
+} // namespace JSC
+
+#endif // DateConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp
new file mode 100644
index 0000000..a725478
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google 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 "DateConversion.h"
+
+#include "UString.h"
+#include <wtf/DateMath.h>
+#include <wtf/StringExtras.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+double parseDate(const UString &date)
+{
+ return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str());
+}
+
+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 timeZoneName[70];
+ struct tm gtm = t;
+ strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+
+ if (timeZoneName[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, timeZoneName);
+ } 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h
new file mode 100644
index 0000000..0d12815
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google 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 DateConversion_h
+#define DateConversion_h
+
+namespace WTF {
+ struct GregorianDateTime;
+}
+
+namespace JSC {
+
+class UString;
+
+double parseDate(const UString&);
+UString formatDate(const WTF::GregorianDateTime&);
+UString formatDateUTCVariant(const WTF::GregorianDateTime&);
+UString formatTime(const WTF::GregorianDateTime&, bool inputIsUTC);
+
+} // namespace JSC
+
+#endif // DateConversion_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp
new file mode 100644
index 0000000..62791ae
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+#include "config.h"
+#include "DateInstance.h"
+
+#include <math.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+struct DateInstance::Cache {
+ double m_gregorianDateTimeCachedForMS;
+ GregorianDateTime m_cachedGregorianDateTime;
+ double m_gregorianDateTimeUTCCachedForMS;
+ GregorianDateTime m_cachedGregorianDateTimeUTC;
+};
+
+const ClassInfo DateInstance::info = {"Date", 0, 0, 0};
+
+DateInstance::DateInstance(PassRefPtr<Structure> 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) {
+ WTF::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) {
+ WTF::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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h
new file mode 100644
index 0000000..3b73521
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DateInstance_h
+#define DateInstance_h
+
+#include "JSWrapperObject.h"
+
+namespace WTF {
+ struct GregorianDateTime;
+}
+
+namespace JSC {
+
+ class DateInstance : public JSWrapperObject {
+ public:
+ explicit DateInstance(PassRefPtr<Structure>);
+ virtual ~DateInstance();
+
+ double internalNumber() const { return internalValue().uncheckedGetNumber(); }
+
+ bool getTime(WTF::GregorianDateTime&, int& offset) const;
+ bool getUTCTime(WTF::GregorianDateTime&) const;
+ bool getTime(double& milliseconds, int& offset) const;
+ bool getUTCTime(double& milliseconds) const;
+
+ static const ClassInfo info;
+
+ void msToGregorianDateTime(double, bool outputIsUTC, WTF::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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp
new file mode 100644
index 0000000..e2482f4
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp
@@ -0,0 +1,1105 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile, 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 "DateConversion.h"
+#include "Error.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "DateInstance.h"
+#include <float.h>
+
+#if !PLATFORM(MAC) && HAVE(LANGINFO_H)
+#include <langinfo.h>
+#endif
+
+#include <limits.h>
+#include <locale.h>
+#include <math.h>
+#include <time.h>
+#include <wtf/Assertions.h>
+#include <wtf/DateMath.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
+
+#if PLATFORM(WINCE) && !PLATFORM(QT)
+extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); //provided by libce
+#endif
+
+using namespace WTF;
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
+
+static JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState*, JSObject*, JSValue, const ArgList&);
+
+static JSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState*, JSObject*, JSValue, const ArgList&);
+
+}
+
+#include "DatePrototype.lut.h"
+
+namespace JSC {
+
+enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
+
+#if PLATFORM(MAC)
+
+// FIXME: Since this is superior to the strftime-based version, why limit this to PLATFORM(MAC)?
+// Instead we should consider using this whenever PLATFORM(CF) is true.
+
+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 JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList& args)
+{
+ CFDateFormatterStyle dateStyle = (format != LocaleTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+ CFDateFormatterStyle timeStyle = (format != LocaleDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+
+ bool useCustomFormat = false;
+ UString customFormatString;
+
+ UString arg0String = args.at(0).toString(exec);
+ if (arg0String == "custom" && !args.at(1).isUndefined()) {
+ useCustomFormat = true;
+ customFormatString = args.at(1).toString(exec);
+ } else if (format == LocaleDateAndTime && !args.at(1).isUndefined()) {
+ dateStyle = styleFromArgString(arg0String, dateStyle);
+ timeStyle = styleFromArgString(args.at(1).toString(exec), timeStyle);
+ } else if (format != LocaleTime && !args.at(0).isUndefined())
+ dateStyle = styleFromArgString(arg0String, dateStyle);
+ else if (format != LocaleDate && !args.at(0).isUndefined())
+ timeStyle = styleFromArgString(arg0String, timeStyle);
+
+ CFLocaleRef locale = CFLocaleCopyCurrent();
+ CFDateFormatterRef formatter = CFDateFormatterCreate(0, locale, dateStyle, timeStyle);
+ CFRelease(locale);
+
+ if (useCustomFormat) {
+ CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, customFormatString.data(), customFormatString.size());
+ CFDateFormatterSetFormat(formatter, customFormatCFString);
+ CFRelease(customFormatCFString);
+ }
+
+ CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, floor(timeInMilliseconds / msPerSecond) - 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), buffer);
+
+ CFRelease(string);
+
+ return jsNontrivialString(exec, UString(buffer, length));
+}
+
+#else // !PLATFORM(MAC)
+
+static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format)
+{
+#if HAVE(LANGINFO_H)
+ static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT };
+#elif PLATFORM(WINCE) && !PLATFORM(QT)
+ // strftime() we are using does not support #
+ static const char* const formatStrings[] = { "%c", "%x", "%X" };
+#else
+ static const char* const formatStrings[] = { "%#c", "%#x", "%X" };
+#endif
+
+ // 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;
+
+#if HAVE(LANGINFO_H)
+ // We do not allow strftime to generate dates with 2-digits years,
+ // both to avoid ambiguity, and a crash in strncpy, for years that
+ // need offset.
+ char* formatString = strdup(nl_langinfo(formats[format]));
+ char* yPos = strchr(formatString, 'y');
+ if (yPos)
+ *yPos = 'Y';
+#endif
+
+ // Do the formatting
+ const int bufsize = 128;
+ char timebuffer[bufsize];
+
+#if HAVE(LANGINFO_H)
+ size_t ret = strftime(timebuffer, bufsize, formatString, &localTM);
+ free(formatString);
+#else
+ size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM);
+#endif
+
+ 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);
+}
+
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList&)
+{
+ GregorianDateTime gregorianDateTime;
+ const bool notUTC = false;
+ dateObject->msToGregorianDateTime(timeInMilliseconds, notUTC, gregorianDateTime);
+ return formatLocaleDate(exec, gregorianDateTime, format);
+}
+
+#endif // !PLATFORM(MAC)
+
+// 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(idx++).toInt32(exec, ok) * msPerHour;
+ }
+
+ // minutes
+ if (maxArgs >= 3 && idx < numArgs && ok) {
+ t->minute = 0;
+ milliseconds += args.at(idx++).toInt32(exec, ok) * msPerMinute;
+ }
+
+ // seconds
+ if (maxArgs >= 2 && idx < numArgs && ok) {
+ t->second = 0;
+ milliseconds += args.at(idx++).toInt32(exec, ok) * msPerSecond;
+ }
+
+ if (!ok)
+ return false;
+
+ // milliseconds
+ if (idx < numArgs) {
+ double millis = args.at(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(idx++).toInt32(exec, ok) - 1900;
+
+ // months
+ if (maxArgs >= 2 && idx < numArgs && ok)
+ t->month = args.at(idx++).toInt32(exec, ok);
+
+ // days
+ if (idx < numArgs && ok) {
+ t->monthDay = 0;
+ *ms += args.at(idx).toInt32(exec, ok) * msPerDay;
+ }
+
+ return ok;
+}
+
+const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState::dateTable};
+
+/* Source for DatePrototype.lut.h
+@begin dateTable
+ toString dateProtoFuncToString DontEnum|Function 0
+ toISOString dateProtoFuncToISOString 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 dateProtoFuncGetTime 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
+ toJSON dateProtoFuncToJSON DontEnum|Function 0
+@end
+*/
+
+// ECMA 15.9.4
+
+DatePrototype::DatePrototype(ExecState* exec, PassRefPtr<Structure> 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL dateProtoFuncToISOString(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 (!isfinite(milli))
+ return jsNontrivialString(exec, "Invalid Date");
+
+ GregorianDateTime t;
+ thisDateObj->msToGregorianDateTime(milli, utc, t);
+ // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second)
+ // 6 for formatting and one for null termination = 23. We add one extra character to allow us to force null termination.
+ char buffer[24];
+ snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second);
+ buffer[sizeof(buffer) - 1] = 0;
+ return jsNontrivialString(exec, buffer);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ if (!thisValue.isObject(&DateInstance::info))
+ 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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");
+
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args);
+}
+
+JSValue JSC_HOST_CALL 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");
+
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args);
+}
+
+JSValue JSC_HOST_CALL 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");
+
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args);
+}
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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(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 JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = false;
+ return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ const bool inputIsUTC = true;
+ return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
+}
+
+JSValue JSC_HOST_CALL 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(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 JSC_HOST_CALL 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);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ JSObject* object = thisValue.toThisObject(exec);
+ if (exec->hadException())
+ return jsNull();
+
+ JSValue toISOValue = object->get(exec, exec->globalData().propertyNames->toISOString);
+ if (exec->hadException())
+ return jsNull();
+
+ CallData callData;
+ CallType callType = toISOValue.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError, "toISOString is not a function");
+
+ JSValue result = call(exec, asObject(toISOValue), callType, callData, object, exec->emptyList());
+ if (exec->hadException())
+ return jsNull();
+ if (result.isObject())
+ return throwError(exec, TypeError, "toISOString did not return a primitive value");
+ return result;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h
new file mode 100644
index 0000000..5f4d0ec
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DatePrototype_h
+#define DatePrototype_h
+
+#include "DateInstance.h"
+
+namespace JSC {
+
+ class ObjectPrototype;
+
+ class DatePrototype : public DateInstance {
+ public:
+ DatePrototype(ExecState*, PassRefPtr<Structure>);
+
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+ };
+
+} // namespace JSC
+
+#endif // DatePrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp
new file mode 100644
index 0000000..1aa9034
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Eric Seidel (eric@webkit.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "Error.h"
+
+#include "ConstructData.h"
+#include "ErrorConstructor.h"
+#include "JSFunction.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;
+ }
+
+ MarkedArgumentBuffer 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, JSC_ERROR_LINENUMBER_PROPERTYNAME), 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, JSC_ERROR_FILENAME_PROPERTYNAME), 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h
new file mode 100644
index 0000000..fb864ee
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Error.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef Error_h
+#define Error_h
+
+#include <stdint.h>
+
+namespace JSC {
+
+ class ExecState;
+ class JSObject;
+ class UString;
+
+ /**
+ * Types of Native Errors available. For custom errors, GeneralError
+ * should be used.
+ */
+ enum ErrorType {
+ GeneralError = 0,
+ EvalError = 1,
+ RangeError = 2,
+ ReferenceError = 3,
+ SyntaxError = 4,
+ TypeError = 5,
+ URIError = 6
+ };
+
+ extern const char* expressionBeginOffsetPropertyName;
+ extern const char* expressionCaretOffsetPropertyName;
+ extern const char* expressionEndOffsetPropertyName;
+
+ class Error {
+ public:
+ static JSObject* create(ExecState*, ErrorType, const UString& message, int lineNumber, intptr_t sourceID, const UString& sourceURL);
+ static JSObject* create(ExecState*, ErrorType, const char* message);
+ };
+
+ JSObject* throwError(ExecState*, ErrorType, const UString& message, int lineNumber, intptr_t sourceID, const UString& sourceURL);
+ JSObject* throwError(ExecState*, ErrorType, const UString& message);
+ JSObject* throwError(ExecState*, ErrorType, const char* message);
+ JSObject* throwError(ExecState*, ErrorType);
+
+#ifdef QT_BUILD_SCRIPT_LIB
+# define JSC_ERROR_FILENAME_PROPERTYNAME "fileName"
+# define JSC_ERROR_LINENUMBER_PROPERTYNAME "lineNumber"
+#else
+# define JSC_ERROR_FILENAME_PROPERTYNAME "sourceURL"
+# define JSC_ERROR_LINENUMBER_PROPERTYNAME "line"
+#endif
+
+} // namespace JSC
+
+#endif // Error_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp
new file mode 100644
index 0000000..07b7e23
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "ErrorConstructor.h"
+
+#include "ErrorPrototype.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
+
+ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<Structure> 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(0).isUndefined())
+ obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(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 JSC_HOST_CALL 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h
new file mode 100644
index 0000000..2dd4124
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ErrorConstructor_h
+#define ErrorConstructor_h
+
+#include "ErrorInstance.h"
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class ErrorPrototype;
+
+ class ErrorConstructor : public InternalFunction {
+ public:
+ ErrorConstructor(ExecState*, PassRefPtr<Structure>, ErrorPrototype*);
+
+ private:
+ virtual ConstructType getConstructData(ConstructData&);
+ virtual CallType getCallData(CallData&);
+ };
+
+ ErrorInstance* constructError(ExecState*, const ArgList&);
+
+} // namespace JSC
+
+#endif // ErrorConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp
new file mode 100644
index 0000000..2e2cdce
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "ErrorInstance.h"
+
+namespace JSC {
+
+const ClassInfo ErrorInstance::info = { "Error", 0, 0, 0 };
+
+ErrorInstance::ErrorInstance(PassRefPtr<Structure> structure)
+ : JSObject(structure)
+{
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h
new file mode 100644
index 0000000..6f9d262
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ErrorInstance_h
+#define ErrorInstance_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ class ErrorInstance : public JSObject {
+ public:
+ explicit ErrorInstance(PassRefPtr<Structure>);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+} // namespace JSC
+
+#endif // ErrorInstance_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp
new file mode 100644
index 0000000..599390e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "ErrorPrototype.h"
+
+#include "JSFunction.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "PrototypeFunction.h"
+#include "UString.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
+
+static JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+
+// ECMA 15.9.4
+ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* 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) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
+}
+
+JSValue JSC_HOST_CALL 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h
new file mode 100644
index 0000000..53d12d9
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ErrorPrototype_h
+#define ErrorPrototype_h
+
+#include "ErrorInstance.h"
+
+namespace JSC {
+
+ class ObjectPrototype;
+
+ class ErrorPrototype : public ErrorInstance {
+ public:
+ ErrorPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ };
+
+} // namespace JSC
+
+#endif // ErrorPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp
new file mode 100644
index 0000000..e63594c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * 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 "ExceptionHelpers.h"
+
+#include "CodeBlock.h"
+#include "CallFrame.h"
+#include "JSGlobalObjectFunctions.h"
+#include "JSObject.h"
+#include "JSNotAnObject.h"
+#include "Interpreter.h"
+#include "Nodes.h"
+
+namespace JSC {
+
+class InterruptedExecutionError : public JSObject {
+public:
+ InterruptedExecutionError(JSGlobalData* globalData)
+ : JSObject(globalData->interruptedExecutionErrorStructure)
+ {
+ }
+
+ virtual bool isWatchdogException() const { return true; }
+
+ virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; }
+};
+
+JSValue createInterruptedExecutionException(JSGlobalData* globalData)
+{
+ return new (globalData) InterruptedExecutionError(globalData);
+}
+
+static JSValue createError(ExecState* exec, ErrorType e, const char* msg)
+{
+ return Error::create(exec, e, msg, -1, -1, 0);
+}
+
+JSValue createStackOverflowError(ExecState* exec)
+{
+ return createError(exec, RangeError, "Maximum call stack size exceeded.");
+}
+
+JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
+{
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
+ UString message = "Can't find variable: ";
+ message.append(ident.ustring());
+ JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
+ return exception;
+}
+
+static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
+{
+ if (!expressionStop || expressionStart > codeBlock->source()->length()) {
+ UString errorText = value.toString(exec);
+ errorText.append(" is ");
+ errorText.append(error);
+ return errorText;
+ }
+
+ UString errorText = "Result of expression ";
+
+ if (expressionStart < expressionStop) {
+ errorText.append('\'');
+ errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
+ errorText.append("' [");
+ errorText.append(value.toString(exec));
+ errorText.append("] is ");
+ } else {
+ // No range information, so give a few characters of context
+ const UChar* data = codeBlock->source()->data();
+ int dataLength = codeBlock->source()->length();
+ int start = expressionStart;
+ int stop = expressionStart;
+ // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
+ // then strip whitespace.
+ while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
+ start--;
+ while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
+ start++;
+ while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
+ stop++;
+ while (stop > expressionStart && isStrWhiteSpace(data[stop]))
+ stop--;
+ errorText.append("near '...");
+ errorText.append(codeBlock->source()->getRange(start, stop));
+ errorText.append("...' [");
+ errorText.append(value.toString(exec));
+ errorText.append("] is ");
+ }
+ errorText.append(error);
+ errorText.append(".");
+ return errorText;
+}
+
+JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+{
+ UString message = "not a valid argument for '";
+ message.append(op);
+ message.append("'");
+
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
+ return exception;
+}
+
+JSObject* createNotAConstructorError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+{
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
+
+ // We're in a "new" expression, so we need to skip over the "new.." part
+ int startPoint = divotPoint - (startOffset ? startOffset - 4 : 0); // -4 for "new "
+ const UChar* data = codeBlock->source()->data();
+ while (startPoint < divotPoint && isStrWhiteSpace(data[startPoint]))
+ startPoint++;
+
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor");
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
+ return exception;
+}
+
+JSValue createNotAFunctionError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+{
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, value, "not a function");
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
+ return exception;
+}
+
+JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState* exec, bool isNull)
+{
+ return new (exec) JSNotAnObjectErrorStub(exec, isNull);
+}
+
+JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, unsigned bytecodeOffset, CodeBlock* codeBlock)
+{
+ // Both op_construct and op_instanceof require a use of op_get_by_id to get
+ // the prototype property from an object. The exception messages for exceptions
+ // thrown by these instances op_get_by_id need to reflect this.
+ OpcodeID followingOpcodeID;
+ if (codeBlock->getByIdExceptionInfoForBytecodeOffset(exec, bytecodeOffset, followingOpcodeID)) {
+ ASSERT(followingOpcodeID == op_construct || followingOpcodeID == op_instanceof);
+ if (followingOpcodeID == op_construct)
+ return createNotAConstructorError(exec, error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock);
+ return createInvalidParamError(exec, "instanceof", error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock);
+ }
+
+ int startOffset = 0;
+ int endOffset = 0;
+ int divotPoint = 0;
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object");
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+ exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
+ exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
+ return exception;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h
new file mode 100644
index 0000000..09d99dc
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -0,0 +1,57 @@
+/*
+ * 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 ExceptionHelpers_h
+#define ExceptionHelpers_h
+
+#include "JSImmediate.h"
+
+namespace JSC {
+
+ class CodeBlock;
+ class ExecState;
+ class Identifier;
+ class Instruction;
+ class JSGlobalData;
+ class JSNotAnObjectErrorStub;
+ class JSObject;
+ class JSValue;
+ class Node;
+
+ JSValue createInterruptedExecutionException(JSGlobalData*);
+ JSValue createStackOverflowError(ExecState*);
+ JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
+ JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull);
+ JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*);
+ JSObject* createNotAConstructorError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
+ JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
+ JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
+
+} // namespace JSC
+
+#endif // ExceptionHelpers_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp
new file mode 100644
index 0000000..f4f5cc8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "FunctionConstructor.h"
+
+#include "FunctionPrototype.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSString.h"
+#include "Parser.h"
+#include "Debugger.h"
+#include "Lexer.h"
+#include "Nodes.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
+
+FunctionConstructor::FunctionConstructor(ExecState* exec, PassRefPtr<Structure> 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 JSC_HOST_CALL 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;
+}
+
+FunctionBodyNode* extractFunctionBody(ProgramNode* program)
+{
+ if (!program)
+ return 0;
+
+ StatementVector& children = program->children();
+ if (children.size() != 1)
+ return 0;
+
+ StatementNode* exprStatement = children[0];
+ ASSERT(exprStatement);
+ ASSERT(exprStatement->isExprStatement());
+ if (!exprStatement || !exprStatement->isExprStatement())
+ return 0;
+
+ ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
+ ASSERT(funcExpr);
+ ASSERT(funcExpr->isFuncExprNode());
+ if (!funcExpr || !funcExpr->isFuncExprNode())
+ return 0;
+
+ FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
+ ASSERT(body);
+ return body;
+}
+
+// ECMA 15.3.2 The Function Constructor
+JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
+{
+ // Functions need to have a space following the opening { due to for web compatibility
+ // see https://bugs.webkit.org/show_bug.cgi?id=24350
+ // We also need \n before the closing } to handle // comments at the end of the last line
+ UString program;
+ if (args.isEmpty())
+ program = "(function() { \n})";
+ else if (args.size() == 1)
+ program = "(function() { " + args.at(0).toString(exec) + "\n})";
+ else {
+ program = "(function(" + args.at(0).toString(exec);
+ for (size_t i = 1; i < args.size() - 1; i++)
+ program += "," + args.at(i).toString(exec);
+ program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})";
+ }
+
+ int errLine;
+ UString errMsg;
+ SourceCode source = makeSource(program, sourceURL, lineNumber);
+ RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
+
+ FunctionBodyNode* body = extractFunctionBody(programNode.get());
+ if (!body)
+ return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
+
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
+ return new (exec) JSFunction(exec, functionName, body, scopeChain.node());
+}
+
+// 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h
new file mode 100644
index 0000000..124b354
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef FunctionConstructor_h
+#define FunctionConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class FunctionPrototype;
+ class ProgramNode;
+ class FunctionBodyNode;
+
+ class FunctionConstructor : public InternalFunction {
+ public:
+ FunctionConstructor(ExecState*, PassRefPtr<Structure>, 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&);
+
+ FunctionBodyNode* extractFunctionBody(ProgramNode*);
+
+} // namespace JSC
+
+#endif // FunctionConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp
new file mode 100644
index 0000000..ff8e57b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "FunctionPrototype.h"
+
+#include "Arguments.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "JSString.h"
+#include "Interpreter.h"
+#include "Lexer.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
+
+static JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*, JSObject*, JSValue, const ArgList&);
+
+FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<Structure> structure)
+ : InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
+{
+ putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
+}
+
+void FunctionPrototype::addFunctionProperties(ExecState* exec, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction)
+{
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
+ *applyFunction = new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply);
+ putDirectFunctionWithoutTransition(exec, *applyFunction, DontEnum);
+ *callFunction = new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall);
+ putDirectFunctionWithoutTransition(exec, *callFunction, DontEnum);
+}
+
+static JSValue JSC_HOST_CALL callFunctionPrototype(ExecState*, JSObject*, JSValue, const ArgList&)
+{
+ return jsUndefined();
+}
+
+// ECMA 15.3.4
+CallType FunctionPrototype::getCallData(CallData& callData)
+{
+ callData.native.function = callFunctionPrototype;
+ return CallTypeHost;
+}
+
+// Functions
+
+// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.)
+static inline void insertSemicolonIfNeeded(UString& functionBody)
+{
+ ASSERT(functionBody[0] == '{');
+ ASSERT(functionBody[functionBody.size() - 1] == '}');
+
+ for (size_t i = functionBody.size() - 2; i > 0; --i) {
+ UChar ch = functionBody[i];
+ if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
+ if (ch != ';' && ch != '}')
+ functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
+ return;
+ }
+ }
+}
+
+JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ if (thisValue.isObject(&JSFunction::info)) {
+ JSFunction* function = asFunction(thisValue);
+ if (!function->isHostFunction()) {
+ UString functionBody = function->body()->toSourceString();
+ insertSemicolonIfNeeded(functionBody);
+ return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + functionBody);
+ }
+ }
+
+ if (thisValue.isObject(&InternalFunction::info)) {
+ InternalFunction* function = asInternalFunction(thisValue);
+ return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n [native code]\n}");
+ }
+
+#ifdef QT_BUILD_SCRIPT_LIB //same error message as in the old engine, and in mozilla
+ return throwError(exec, TypeError, "Function.prototype.toString called on incompatible object");
+#else
+ return throwError(exec, TypeError);
+#endif
+}
+
+JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ CallData callData;
+ CallType callType = thisValue.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ JSValue array = args.at(1);
+
+ MarkedArgumentBuffer applyArgs;
+ if (!array.isUndefinedOrNull()) {
+ if (!array.isObject())
+ return throwError(exec, TypeError);
+ if (asObject(array)->classInfo() == &Arguments::info)
+ asArguments(array)->fillArgList(exec, applyArgs);
+ else if (isJSArray(&exec->globalData(), array))
+ asArray(array)->fillArgList(exec, applyArgs);
+ else if (asObject(array)->inherits(&JSArray::info)) {
+ unsigned length = asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
+ for (unsigned i = 0; i < length; ++i)
+ applyArgs.append(asArray(array)->get(exec, i));
+ } else
+ return throwError(exec, TypeError);
+ }
+
+ return call(exec, thisValue, callType, callData, args.at(0), applyArgs);
+}
+
+JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ CallData callData;
+ CallType callType = thisValue.getCallData(callData);
+ if (callType == CallTypeNone)
+ return throwError(exec, TypeError);
+
+ ArgList callArgs;
+ args.getSlice(1, callArgs);
+ return call(exec, thisValue, callType, callData, args.at(0), callArgs);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h
new file mode 100644
index 0000000..607ddab
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef FunctionPrototype_h
+#define FunctionPrototype_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class PrototypeFunction;
+
+ class FunctionPrototype : public InternalFunction {
+ public:
+ FunctionPrototype(ExecState*, PassRefPtr<Structure>);
+ void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction);
+
+ static PassRefPtr<Structure> createStructure(JSValue proto)
+ {
+ return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ }
+
+ private:
+ virtual CallType getCallData(CallData&);
+ };
+
+} // namespace JSC
+
+#endif // FunctionPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp
new file mode 100644
index 0000000..cd1b40a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "GetterSetter.h"
+
+#include "JSObject.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+void GetterSetter::mark()
+{
+ JSCell::mark();
+
+ if (m_getter && !m_getter->marked())
+ m_getter->mark();
+ if (m_setter && !m_setter->marked())
+ m_setter->mark();
+}
+
+JSValue GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+ ASSERT_NOT_REACHED();
+ return jsNull();
+}
+
+bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
+{
+ ASSERT_NOT_REACHED();
+ number = 0;
+ value = JSValue();
+ return true;
+}
+
+bool GetterSetter::toBoolean(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+double GetterSetter::toNumber(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return 0.0;
+}
+
+UString GetterSetter::toString(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return UString::null();
+}
+
+JSObject* GetterSetter::toObject(ExecState* exec) const
+{
+ ASSERT_NOT_REACHED();
+ return jsNull().toObject(exec);
+}
+
+bool GetterSetter::isGetterSetter() const
+{
+ return true;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h
new file mode 100644
index 0000000..e6b74a1
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GetterSetter_h
+#define GetterSetter_h
+
+#include "JSCell.h"
+
+namespace JSC {
+
+ class JSObject;
+
+ // This is an internal value object which stores getter and setter functions
+ // for a property.
+ class GetterSetter : public JSCell {
+ public:
+ GetterSetter()
+ : JSCell(0)
+ , m_getter(0)
+ , m_setter(0)
+ {
+ }
+
+ virtual void mark();
+
+ JSObject* getter() const { return m_getter; }
+ void setGetter(JSObject* getter) { m_getter = getter; }
+ JSObject* setter() const { return m_setter; }
+ void setSetter(JSObject* setter) { m_setter = setter; }
+
+ private:
+ virtual bool isGetterSetter() const;
+
+ virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
+ virtual bool toBoolean(ExecState*) const;
+ virtual double toNumber(ExecState*) const;
+ virtual UString toString(ExecState*) const;
+ virtual JSObject* toObject(ExecState*) const;
+
+ JSObject* m_getter;
+ JSObject* m_setter;
+ };
+
+ GetterSetter* asGetterSetter(JSValue);
+
+ inline GetterSetter* asGetterSetter(JSValue value)
+ {
+ ASSERT(asCell(value)->isGetterSetter());
+ return static_cast<GetterSetter*>(asCell(value));
+ }
+
+
+} // namespace JSC
+
+#endif // GetterSetter_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp
new file mode 100644
index 0000000..b0d4c25
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "GlobalEvalFunction.h"
+
+#include "JSGlobalObject.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction);
+
+GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, PassRefPtr<Structure> 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h
new file mode 100644
index 0000000..49b1847
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GlobalEvalFunction_h
+#define GlobalEvalFunction_h
+
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ class JSGlobalObject;
+
+ class GlobalEvalFunction : public PrototypeFunction {
+ public:
+ GlobalEvalFunction(ExecState*, PassRefPtr<Structure>, 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp
new file mode 100644
index 0000000..7db723b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ *
+ */
+
+#include "config.h"
+#include "Identifier.h"
+
+#include "CallFrame.h"
+#include <new> // for placement new
+#include <string.h> // for strlen
+#include <wtf/Assertions.h>
+#include <wtf/FastMalloc.h>
+#include <wtf/HashSet.h>
+
+namespace JSC {
+
+typedef HashMap<const char*, RefPtr<UString::Rep>, PtrHash<const char*> > LiteralIdentifierTable;
+
+class IdentifierTable : public FastAllocBase {
+public:
+ ~IdentifierTable()
+ {
+ HashSet<UString::Rep*>::iterator end = m_table.end();
+ for (HashSet<UString::Rep*>::iterator iter = m_table.begin(); iter != end; ++iter)
+ (*iter)->setIdentifierTable(0);
+ }
+
+ std::pair<HashSet<UString::Rep*>::iterator, bool> add(UString::Rep* value)
+ {
+ std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add(value);
+ (*result.first)->setIdentifierTable(this);
+ return result;
+ }
+
+ template<typename U, typename V>
+ std::pair<HashSet<UString::Rep*>::iterator, bool> add(U value)
+ {
+ std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add<U, V>(value);
+ (*result.first)->setIdentifierTable(this);
+ return result;
+ }
+
+ void remove(UString::Rep* r) { m_table.remove(r); }
+
+ LiteralIdentifierTable& literalTable() { return m_literalTable; }
+
+private:
+ HashSet<UString::Rep*> m_table;
+ LiteralIdentifierTable m_literalTable;
+};
+
+IdentifierTable* createIdentifierTable()
+{
+ return new IdentifierTable;
+}
+
+void deleteIdentifierTable(IdentifierTable* table)
+{
+ delete table;
+}
+
+bool Identifier::equal(const UString::Rep* r, const char* s)
+{
+ int length = r->len;
+ const UChar* d = r->data();
+ for (int i = 0; i != length; ++i)
+ if (d[i] != (unsigned char)s[i])
+ return false;
+ return s[length] == 0;
+}
+
+bool Identifier::equal(const UString::Rep* r, const UChar* s, int length)
+{
+ if (r->len != length)
+ return false;
+ const UChar* d = r->data();
+ for (int i = 0; i != length; ++i)
+ if (d[i] != s[i])
+ return false;
+ return true;
+}
+
+struct CStringTranslator {
+ static unsigned hash(const char* c)
+ {
+ return UString::Rep::computeHash(c);
+ }
+
+ static bool equal(UString::Rep* r, const char* s)
+ {
+ return Identifier::equal(r, s);
+ }
+
+ static void translate(UString::Rep*& location, const char* c, unsigned hash)
+ {
+ size_t length = strlen(c);
+ UChar* d = static_cast<UChar*>(fastMalloc(sizeof(UChar) * length));
+ for (size_t i = 0; i != length; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+
+ UString::Rep* r = UString::Rep::create(d, static_cast<int>(length)).releaseRef();
+ r->_hash = hash;
+
+ location = r;
+ }
+};
+
+PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
+{
+ if (!c) {
+ UString::Rep::null().hash();
+ return &UString::Rep::null();
+ }
+ if (!c[0]) {
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
+ }
+ if (!c[1])
+ return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
+
+ IdentifierTable& identifierTable = *globalData->identifierTable;
+ LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable();
+
+ const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c);
+ if (iter != literalIdentifierTable.end())
+ return iter->second;
+
+ pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, CStringTranslator>(c);
+
+ // If the string is newly-translated, then we need to adopt it.
+ // The boolean in the pair tells us if that is so.
+ RefPtr<UString::Rep> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first;
+
+ literalIdentifierTable.add(c, addedString.get());
+
+ return addedString.release();
+}
+
+PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const char* c)
+{
+ return add(&exec->globalData(), c);
+}
+
+struct UCharBuffer {
+ const UChar* s;
+ unsigned int length;
+};
+
+struct UCharBufferTranslator {
+ static unsigned hash(const UCharBuffer& buf)
+ {
+ return UString::Rep::computeHash(buf.s, buf.length);
+ }
+
+ static bool equal(UString::Rep* str, const UCharBuffer& buf)
+ {
+ return Identifier::equal(str, buf.s, buf.length);
+ }
+
+ static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash)
+ {
+ UChar* d = static_cast<UChar*>(fastMalloc(sizeof(UChar) * buf.length));
+ for (unsigned i = 0; i != buf.length; i++)
+ d[i] = buf.s[i];
+
+ UString::Rep* r = UString::Rep::create(d, buf.length).releaseRef();
+ r->_hash = hash;
+
+ location = r;
+ }
+};
+
+PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* s, int length)
+{
+ if (length == 1) {
+ UChar c = s[0];
+ if (c <= 0xFF)
+ return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
+ }
+ if (!length) {
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
+ }
+ UCharBuffer buf = {s, length};
+ pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, UCharBufferTranslator>(buf);
+
+ // If the string is newly-translated, then we need to adopt it.
+ // The boolean in the pair tells us if that is so.
+ return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
+}
+
+PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int length)
+{
+ return add(&exec->globalData(), s, length);
+}
+
+PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r)
+{
+ ASSERT(!r->identifierTable());
+ if (r->len == 1) {
+ UChar c = r->data()[0];
+ if (c <= 0xFF)
+ r = globalData->smallStrings.singleCharacterStringRep(c);
+ if (r->identifierTable()) {
+#ifndef NDEBUG
+ checkSameIdentifierTable(globalData, r);
+#endif
+ return r;
+ }
+ }
+ if (!r->len) {
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
+ }
+ return *globalData->identifierTable->add(r).first;
+}
+
+PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep* r)
+{
+ return addSlowCase(&exec->globalData(), r);
+}
+
+void Identifier::remove(UString::Rep* r)
+{
+ r->identifierTable()->remove(r);
+}
+
+#ifndef NDEBUG
+
+void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep* rep)
+{
+ ASSERT(rep->identifierTable() == exec->globalData().identifierTable);
+}
+
+void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep* rep)
+{
+ ASSERT(rep->identifierTable() == globalData->identifierTable);
+}
+
+#else
+
+void Identifier::checkSameIdentifierTable(ExecState*, UString::Rep*)
+{
+}
+
+void Identifier::checkSameIdentifierTable(JSGlobalData*, UString::Rep*)
+{
+}
+
+#endif
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h
new file mode 100644
index 0000000..631cf42
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 Identifier_h
+#define Identifier_h
+
+#include "JSGlobalData.h"
+#include "UString.h"
+
+namespace JSC {
+
+ class ExecState;
+
+ class Identifier {
+ friend class Structure;
+ public:
+ Identifier() { }
+
+ Identifier(ExecState* exec, const char* s) : _ustring(add(exec, s)) { } // Only to be used with string literals.
+ Identifier(ExecState* exec, const UChar* s, int length) : _ustring(add(exec, s, length)) { }
+ Identifier(ExecState* exec, UString::Rep* rep) : _ustring(add(exec, rep)) { }
+ Identifier(ExecState* exec, const UString& s) : _ustring(add(exec, s.rep())) { }
+
+ Identifier(JSGlobalData* globalData, const char* s) : _ustring(add(globalData, s)) { } // Only to be used with string literals.
+ Identifier(JSGlobalData* globalData, const UChar* s, int length) : _ustring(add(globalData, s, length)) { }
+ Identifier(JSGlobalData* globalData, UString::Rep* rep) : _ustring(add(globalData, rep)) { }
+ Identifier(JSGlobalData* globalData, const UString& s) : _ustring(add(globalData, s.rep())) { }
+
+ // Special constructor for cases where we overwrite an object in place.
+ Identifier(PlacementNewAdoptType) : _ustring(PlacementNewAdopt) { }
+
+ const UString& ustring() const { return _ustring; }
+
+ const UChar* data() const { return _ustring.data(); }
+ int size() const { return _ustring.size(); }
+
+ const char* ascii() const { return _ustring.ascii(); }
+
+ static Identifier from(ExecState* exec, unsigned y) { return Identifier(exec, UString::from(y)); }
+
+ bool isNull() const { return _ustring.isNull(); }
+ bool isEmpty() const { return _ustring.isEmpty(); }
+
+ uint32_t toUInt32(bool* ok) const { return _ustring.toUInt32(ok); }
+ uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const { return _ustring.toUInt32(ok, tolerateEmptyString); };
+ uint32_t toStrictUInt32(bool* ok) const { return _ustring.toStrictUInt32(ok); }
+ unsigned toArrayIndex(bool* ok) const { return _ustring.toArrayIndex(ok); }
+ double toDouble() const { return _ustring.toDouble(); }
+
+ friend bool operator==(const Identifier&, const Identifier&);
+ friend bool operator!=(const Identifier&, const Identifier&);
+
+ friend bool operator==(const Identifier&, const char*);
+ friend bool operator!=(const Identifier&, const char*);
+
+ static void remove(UString::Rep*);
+
+ static bool equal(const UString::Rep*, const char*);
+ static bool equal(const UString::Rep*, const UChar*, int length);
+ static bool equal(const UString::Rep* a, const UString::Rep* b) { return JSC::equal(a, b); }
+
+ static PassRefPtr<UString::Rep> add(ExecState*, const char*); // Only to be used with string literals.
+ static PassRefPtr<UString::Rep> add(JSGlobalData*, const char*); // Only to be used with string literals.
+
+ private:
+ UString _ustring;
+
+ static bool equal(const Identifier& a, const Identifier& b) { return a._ustring.rep() == b._ustring.rep(); }
+ static bool equal(const Identifier& a, const char* b) { return equal(a._ustring.rep(), b); }
+
+ static PassRefPtr<UString::Rep> add(ExecState*, const UChar*, int length);
+ static PassRefPtr<UString::Rep> add(JSGlobalData*, const UChar*, int length);
+
+ static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r)
+ {
+ if (r->identifierTable()) {
+#ifndef NDEBUG
+ checkSameIdentifierTable(exec, r);
+#endif
+ return r;
+ }
+ return addSlowCase(exec, r);
+ }
+ static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r)
+ {
+ if (r->identifierTable()) {
+#ifndef NDEBUG
+ checkSameIdentifierTable(globalData, r);
+#endif
+ return r;
+ }
+ return addSlowCase(globalData, r);
+ }
+
+ static PassRefPtr<UString::Rep> addSlowCase(ExecState*, UString::Rep* r);
+ static PassRefPtr<UString::Rep> addSlowCase(JSGlobalData*, UString::Rep* r);
+
+ static void checkSameIdentifierTable(ExecState*, UString::Rep*);
+ static void checkSameIdentifierTable(JSGlobalData*, UString::Rep*);
+ };
+
+ inline bool operator==(const Identifier& a, const Identifier& b)
+ {
+ return Identifier::equal(a, b);
+ }
+
+ inline bool operator!=(const Identifier& a, const Identifier& b)
+ {
+ return !Identifier::equal(a, b);
+ }
+
+ inline bool operator==(const Identifier& a, const char* b)
+ {
+ return Identifier::equal(a, b);
+ }
+
+ inline bool operator!=(const Identifier& a, const char* b)
+ {
+ return !Identifier::equal(a, b);
+ }
+
+ IdentifierTable* createIdentifierTable();
+ void deleteIdentifierTable(IdentifierTable*);
+
+} // namespace JSC
+
+#endif // Identifier_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp
new file mode 100644
index 0000000..a0620e7
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -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.
+ * 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 "JSImmediate.h"
+#include "Collector.h"
+#include "dtoa.h"
+#include "Identifier.h"
+#include "JSGlobalObject.h"
+#include "UString.h"
+#include <wtf/DateMath.h>
+#include <wtf/Threading.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
+static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
+#endif
+
+static void initializeThreadingOnce()
+{
+ WTF::initializeThreading();
+ initializeUString();
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ s_dtoaP5Mutex = new Mutex;
+ WTF::initializeDates();
+#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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.h
new file mode 100644
index 0000000..1a93ccb
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp
new file mode 100644
index 0000000..b5c9571
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "InternalFunction.h"
+
+#include "FunctionPrototype.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(InternalFunction);
+
+const ClassInfo InternalFunction::info = { "Function", 0, 0, 0 };
+
+const ClassInfo* InternalFunction::classInfo() const
+{
+ return &info;
+}
+
+InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structure> 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();
+}
+
+const UString InternalFunction::displayName(JSGlobalData* globalData)
+{
+ JSValue displayName = getDirect(globalData->propertyNames->displayName);
+
+ if (displayName && isJSString(globalData, displayName))
+ return asString(displayName)->value();
+
+ return UString::null();
+}
+
+const UString InternalFunction::calculatedDisplayName(JSGlobalData* globalData)
+{
+ const UString explicitName = displayName(globalData);
+
+ if (!explicitName.isEmpty())
+ return explicitName;
+
+ return name(globalData);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h
new file mode 100644
index 0000000..310644c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef InternalFunction_h
+#define InternalFunction_h
+
+#include "JSObject.h"
+#include "Identifier.h"
+
+namespace JSC {
+
+ class FunctionPrototype;
+
+ class InternalFunction : public JSObject {
+ public:
+ virtual const ClassInfo* classInfo() const;
+ static JS_EXPORTDATA const ClassInfo info;
+
+ const UString& name(JSGlobalData*);
+ const UString displayName(JSGlobalData*);
+ const UString calculatedDisplayName(JSGlobalData*);
+
+ static PassRefPtr<Structure> createStructure(JSValue proto)
+ {
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
+ }
+
+ protected:
+ InternalFunction(PassRefPtr<Structure> structure) : JSObject(structure) { }
+ InternalFunction(JSGlobalData*, PassRefPtr<Structure>, 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp
new file mode 100644
index 0000000..184a9cb
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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 "Interpreter.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().activationStructure, new JSActivationData(functionBody, callFrame->registers()))
+{
+}
+
+JSActivation::~JSActivation()
+{
+ delete d();
+}
+
+void JSActivation::mark()
+{
+ Base::mark();
+
+ Register* registerArray = d()->registerArray.get();
+ if (!registerArray)
+ return;
+
+ size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_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().m_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.jsValue() && !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* exec, 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;
+ JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot);
+}
+
+bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+{
+ if (propertyName == exec->propertyNames().arguments)
+ return false;
+
+ return Base::deleteProperty(exec, propertyName, checkDontDelete);
+}
+
+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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h
new file mode 100644
index 0000000..b48ef25
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h
@@ -0,0 +1,98 @@
+/*
+ * 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 isActivationObject() const { return true; }
+
+ 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, bool checkDontDelete = true);
+
+ virtual JSObject* toThisObject(ExecState*) const;
+
+ void copyRegisters(Arguments* arguments);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+
+ private:
+ struct JSActivationData : public JSVariableObjectData {
+ JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
+ : JSVariableObjectData(&functionBody->generatedBytecode().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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp
new file mode 100644
index 0000000..a8207e3
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp
@@ -0,0 +1,1073 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "JSArray.h"
+
+#include "ArrayPrototype.h"
+#include "CachedCall.h"
+#include "PropertyNameArray.h"
+#include <wtf/AVLTree.h>
+#include <wtf/Assertions.h>
+#include <wtf/OwnPtr.h>
+#include <Operations.h>
+
+#define CHECK_ARRAY_CONSISTENCY 0
+
+using namespace std;
+using namespace WTF;
+
+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<Structure> structure)
+ : JSObject(structure)
+{
+ unsigned initialCapacity = 0;
+
+ m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
+ m_fastAccessCutoff = 0;
+ m_storage->m_vectorLength = initialCapacity;
+ m_storage->m_length = 0;
+
+ checkConsistency();
+}
+
+JSArray::JSArray(PassRefPtr<Structure> 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(PassRefPtr<Structure> 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;
+
+ m_storage = storage;
+
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(length));
+
+ 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;
+
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
+
+ if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
+ for (unsigned j = vectorLength; j < newVectorLength; ++j)
+ storage->m_vector[j] = JSValue();
+ 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] = JSValue();
+ 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 checkDontDelete)
+{
+ bool isArrayIndex;
+ unsigned i = propertyName.toArrayIndex(&isArrayIndex);
+ if (isArrayIndex)
+ return deleteProperty(exec, i, checkDontDelete);
+
+ if (propertyName == exec->propertyNames().length)
+ return false;
+
+ return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
+}
+
+bool JSArray::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete)
+{
+ checkConsistency();
+
+ ArrayStorage* storage = m_storage;
+
+ if (i < storage->m_vectorLength) {
+ JSValue& valueSlot = storage->m_vector[i];
+ if (!valueSlot) {
+ checkConsistency();
+ return false;
+ }
+ valueSlot = JSValue();
+ --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), checkDontDelete);
+
+ return false;
+}
+
+void JSArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes)
+{
+ // 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, listedAttributes);
+}
+
+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;
+
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
+ storage->m_vectorLength = newVectorLength;
+
+ for (unsigned i = vectorLength; i < newVectorLength; ++i)
+ storage->m_vector[i] = JSValue();
+
+ 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 = JSValue();
+ 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 = JSValue();
+ --m_storage->m_numValuesInVector;
+ m_fastAccessCutoff = length;
+ } else if (length < m_storage->m_vectorLength) {
+ JSValue& valueSlot = m_storage->m_vector[length];
+ result = valueSlot;
+ valueSlot = JSValue();
+ 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();
+ }
+ }
+}
+
+static int compareNumbersForQSort(const void* a, const void* b)
+{
+ double da = static_cast<const JSValue*>(a)->uncheckedGetNumber();
+ double db = static_cast<const JSValue*>(b)->uncheckedGetNumber();
+ return (da > db) - (da < db);
+}
+
+typedef std::pair<JSValue, UString> ValueStringPair;
+
+static int compareByStringPairForQSort(const void* a, const void* b)
+{
+ const ValueStringPair* va = static_cast<const ValueStringPair*>(a);
+ const ValueStringPair* vb = static_cast<const ValueStringPair*>(b);
+ return compare(va->second, vb->second);
+}
+
+void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
+{
+ unsigned lengthNotIncludingUndefined = compactForSorting();
+ if (m_storage->m_sparseValueMap) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+
+ if (!lengthNotIncludingUndefined)
+ return;
+
+ bool allValuesAreNumbers = true;
+ size_t size = m_storage->m_numValuesInVector;
+ for (size_t i = 0; i < size; ++i) {
+ if (!m_storage->m_vector[i].isNumber()) {
+ allValuesAreNumbers = false;
+ break;
+ }
+ }
+
+ if (!allValuesAreNumbers)
+ return sort(exec, compareFunction, callType, callData);
+
+ // For numeric comparison, which is fast, qsort is faster than mergesort. We
+ // also don't require mergesort's stability, since there's no user visible
+ // side-effect from swapping the order of equal primitive values.
+ qsort(m_storage->m_vector, size, sizeof(JSValue), compareNumbersForQSort);
+
+ checkConsistency(SortConsistencyCheck);
+}
+
+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<ValueStringPair> 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(ValueStringPair), 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(ValueStringPair), 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;
+ OwnPtr<CachedCall> m_cachedCall;
+
+ 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;
+
+ double compareResult;
+ if (m_cachedCall) {
+ m_cachedCall->setThis(m_globalThisValue);
+ m_cachedCall->setArgument(0, va);
+ m_cachedCall->setArgument(1, vb);
+ compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame());
+ } else {
+ MarkedArgumentBuffer arguments;
+ arguments.append(va);
+ arguments.append(vb);
+ 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 (callType == CallTypeJS)
+ tree.abstractor().m_cachedCall.set(new CachedCall(exec, asFunction(compareFunction), 2, exec->exceptionSlot()));
+
+ 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) {
+ JSValue v = m_storage->m_vector[i];
+ if (v) {
+ 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] = JSValue();
+
+ m_fastAccessCutoff = newUsedVectorLength;
+ m_storage->m_numValuesInVector = newUsedVectorLength;
+
+ checkConsistency(SortConsistencyCheck);
+}
+
+void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& 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));
+}
+
+void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
+{
+ ASSERT(m_storage->m_length == maxSize);
+ UNUSED_PARAM(maxSize);
+ unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff);
+ unsigned i = 0;
+ for (; i < fastAccessLength; ++i)
+ buffer[i] = getIndex(i);
+ uint32_t size = m_storage->m_length;
+ for (; i < size; ++i)
+ buffer[i] = 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) {
+ JSValue v = storage->m_vector[i];
+ if (v) {
+ 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] = JSValue();
+
+ 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)
+{
+ MarkedArgumentBuffer values;
+ values.append(singleItemValue);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+}
+
+JSArray* constructArray(ExecState* exec, const ArgList& values)
+{
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h
new file mode 100644
index 0000000..73e1711
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef JSArray_h
+#define JSArray_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
+
+ struct ArrayStorage {
+ unsigned m_length;
+ unsigned m_vectorLength;
+ unsigned m_numValuesInVector;
+ SparseArrayValueMap* m_sparseValueMap;
+ void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
+ JSValue m_vector[1];
+ };
+
+ class JSArray : public JSObject {
+ friend class JIT;
+
+ public:
+ explicit JSArray(PassRefPtr<Structure>);
+ JSArray(PassRefPtr<Structure>, unsigned initialLength);
+ JSArray(PassRefPtr<Structure>, 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 JS_EXPORTDATA 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 sortNumeric(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*, MarkedArgumentBuffer&);
+ void copyToRegisters(ExecState*, Register*, uint32_t);
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+
+ protected:
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
+ virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype);
+ virtual void mark();
+
+ 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));
+ }
+
+ inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; }
+
+} // namespace JSC
+
+#endif // JSArray_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp
new file mode 100644
index 0000000..d00b69c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSByteArray.h"
+
+#include "JSGlobalObject.h"
+#include "PropertyNameArray.h"
+
+using namespace WTF;
+
+namespace JSC {
+
+const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", 0, 0, 0 };
+
+JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteArray* storage, const JSC::ClassInfo* classInfo)
+ : JSObject(structure)
+ , m_storage(storage)
+ , m_classInfo(classInfo)
+{
+ putDirect(exec->globalData().propertyNames->length, jsNumber(exec, m_storage->length()), ReadOnly | DontDelete);
+}
+
+PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
+{
+ PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType));
+ return result;
+}
+
+bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ bool ok;
+ unsigned index = propertyName.toUInt32(&ok, false);
+ if (ok && canAccessIndex(index)) {
+ slot.setValue(getIndex(exec, index));
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+ if (canAccessIndex(propertyName)) {
+ slot.setValue(getIndex(exec, propertyName));
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
+}
+
+void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+{
+ bool ok;
+ unsigned index = propertyName.toUInt32(&ok, false);
+ if (ok) {
+ setIndex(exec, index, value);
+ return;
+ }
+ JSObject::put(exec, propertyName, value, slot);
+}
+
+void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value)
+{
+ setIndex(exec, propertyName, value);
+}
+
+void JSByteArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes)
+{
+ unsigned length = m_storage->length();
+ for (unsigned i = 0; i < length; ++i)
+ propertyNames.add(Identifier::from(exec, i));
+ JSObject::getPropertyNames(exec, propertyNames, listedAttributes);
+}
+
+}
+
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h
new file mode 100644
index 0000000..c43c3ea
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSByteArray_h
+#define JSByteArray_h
+
+#include "JSObject.h"
+
+#include <wtf/ByteArray.h>
+
+namespace JSC {
+
+ class JSByteArray : public JSObject {
+ friend class VPtrSet;
+ public:
+ bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
+ JSValue getIndex(ExecState* exec, unsigned i)
+ {
+ ASSERT(canAccessIndex(i));
+ return jsNumber(exec, m_storage->data()[i]);
+ }
+
+ void setIndex(unsigned i, int value)
+ {
+ ASSERT(canAccessIndex(i));
+ if (value & ~0xFF) {
+ if (value < 0)
+ value = 0;
+ else
+ value = 255;
+ }
+ m_storage->data()[i] = static_cast<unsigned char>(value);
+ }
+
+ void setIndex(unsigned i, double value)
+ {
+ ASSERT(canAccessIndex(i));
+ if (!(value > 0)) // Clamp NaN to 0
+ value = 0;
+ else if (value > 255)
+ value = 255;
+ m_storage->data()[i] = static_cast<unsigned char>(value + 0.5);
+ }
+
+ void setIndex(ExecState* exec, unsigned i, JSValue value)
+ {
+ double byteValue = value.toNumber(exec);
+ if (exec->hadException())
+ return;
+ if (canAccessIndex(i))
+ setIndex(i, byteValue);
+ }
+
+ JSByteArray(ExecState* exec, PassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
+ static PassRefPtr<Structure> createStructure(JSValue prototype);
+
+ virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
+ virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+ virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
+ virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);
+
+ virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = Structure::Prototype);
+
+ virtual const ClassInfo* classInfo() const { return m_classInfo; }
+ static const ClassInfo s_defaultInfo;
+
+ size_t length() const { return m_storage->length(); }
+
+ WTF::ByteArray* storage() const { return m_storage.get(); }
+
+ private:
+ enum VPtrStealingHackType { VPtrStealingHack };
+ JSByteArray(VPtrStealingHackType)
+ : JSObject(createStructure(jsNull()))
+ , m_classInfo(0)
+ {
+ }
+
+ RefPtr<WTF::ByteArray> m_storage;
+ const ClassInfo* m_classInfo;
+ };
+
+ JSByteArray* asByteArray(JSValue value);
+ inline JSByteArray* asByteArray(JSValue value)
+ {
+ return static_cast<JSByteArray*>(asCell(value));
+ }
+
+ inline bool isJSByteArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsByteArrayVPtr; }
+
+} // namespace JSC
+
+#endif // JSByteArray_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp
new file mode 100644
index 0000000..10a91f7
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSCell.h"
+
+#include "JSFunction.h"
+#include "JSString.h"
+#include "JSObject.h"
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+#if defined NAN && defined INFINITY
+
+extern const double NaN = NAN;
+extern const double Inf = INFINITY;
+
+#else // !(defined NAN && defined INFINITY)
+
+// The trick is to define the NaN and Inf globals with a different type than the declaration.
+// This trick works because the mangled name of the globals does not include the type, although
+// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of
+// characters don't necessarily need the same alignment doubles do, but for now it seems to work.
+// It would be good to figure out a 100% clean way that still avoids code that runs at init time.
+
+// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere,
+// while NaN_double has to be 4-byte aligned for 32-bits.
+// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading.
+
+static const union {
+ struct {
+ unsigned char NaN_Bytes[8];
+ unsigned char Inf_Bytes[8];
+ } bytes;
+
+ struct {
+ double NaN_Double;
+ double Inf_Double;
+ } doubles;
+
+} NaNInf = { {
+#if PLATFORM(BIG_ENDIAN)
+ { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 },
+ { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
+#elif PLATFORM(MIDDLE_ENDIAN)
+ { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 },
+ { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
+#else
+ { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f },
+ { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
+#endif
+} } ;
+
+extern const double NaN = NaNInf.doubles.NaN_Double;
+extern const double Inf = NaNInf.doubles.Inf_Double;
+
+#endif // !(defined NAN && defined INFINITY)
+
+void* JSCell::operator new(size_t size, ExecState* exec)
+{
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return exec->heap()->inlineAllocate(size);
+#else
+ return exec->heap()->allocate(size);
+#endif
+}
+
+bool JSCell::getUInt32(uint32_t&) const
+{
+ return false;
+}
+
+bool JSCell::getTruncatedInt32(int32_t&) const
+{
+ return false;
+}
+
+bool JSCell::getTruncatedUInt32(uint32_t&) const
+{
+ return false;
+}
+
+bool JSCell::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, bool checkDontDelete)
+{
+ return toObject(exec)->deleteProperty(exec, identifier, checkDontDelete);
+}
+
+bool JSCell::deleteProperty(ExecState* exec, unsigned identifier, bool checkDontDelete)
+{
+ return toObject(exec)->deleteProperty(exec, identifier, checkDontDelete);
+}
+
+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 JSValue();
+}
+
+bool JSCell::isGetterSetter() const
+{
+ return false;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h
new file mode 100644
index 0000000..4743baf
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSCell_h
+#define JSCell_h
+
+#include <wtf/Noncopyable.h>
+#include "Structure.h"
+#include "JSValue.h"
+#include "JSImmediate.h"
+#include "Collector.h"
+
+namespace JSC {
+
+ class JSCell : public NoncopyableCustomAllocated {
+ friend class GetterSetter;
+ friend class Heap;
+ friend class JIT;
+ friend class JSNumberCell;
+ friend class JSObject;
+ friend class JSPropertyNameIterator;
+ friend class JSString;
+ friend class JSValue;
+ friend class VPtrSet;
+
+ private:
+ explicit JSCell(Structure*);
+ 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;
+
+ Structure* structure() const;
+
+ // Extracting the value.
+ 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.
+ // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*.
+ virtual bool getUInt32(uint32_t&) const;
+ virtual bool getTruncatedInt32(int32_t&) const;
+ virtual bool getTruncatedUInt32(uint32_t&) const;
+
+ // Basic conversions.
+ virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&) = 0;
+ virtual bool toBoolean(ExecState*) const = 0;
+ virtual double toNumber(ExecState*) const = 0;
+ virtual UString toString(ExecState*) const = 0;
+ virtual JSObject* toObject(ExecState*) const = 0;
+
+ // 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, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
+
+ 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&);
+
+ Structure* m_structure;
+ };
+
+ JSCell* asCell(JSValue);
+
+ inline JSCell* asCell(JSValue value)
+ {
+ return value.asCell();
+ }
+
+ inline JSCell::JSCell(Structure* structure)
+ : m_structure(structure)
+ {
+ }
+
+ inline JSCell::~JSCell()
+ {
+ }
+
+ inline bool JSCell::isNumber() const
+ {
+ return Heap::isNumber(const_cast<JSCell*>(this));
+ }
+
+ inline bool JSCell::isObject() const
+ {
+ return m_structure->typeInfo().type() == ObjectType;
+ }
+
+ inline bool JSCell::isString() const
+ {
+ return m_structure->typeInfo().type() == StringType;
+ }
+
+ inline Structure* JSCell::structure() const
+ {
+ return m_structure;
+ }
+
+ inline bool JSCell::marked() const
+ {
+ return Heap::isCellMarked(this);
+ }
+
+ inline void JSCell::mark()
+ {
+ return Heap::markCell(this);
+ }
+
+ ALWAYS_INLINE JSCell* JSValue::asCell() const
+ {
+ ASSERT(isCell());
+ return m_ptr;
+ }
+
+ inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
+ {
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return globalData->heap.inlineAllocate(size);
+#else
+ return globalData->heap.allocate(size);
+#endif
+ }
+
+ // --- JSValue inlines ----------------------------
+
+ 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 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::toThisObject(asValue(), exec);
+ return asCell()->toThisObject(exec);
+ }
+
+ inline bool JSValue::needsThisConversion() const
+ {
+ if (UNLIKELY(JSImmediate::isImmediate(asValue())))
+ return true;
+ return asCell()->structure()->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()) ? JSValue() : asCell()->getJSNumber();
+ }
+
+} // namespace JSC
+
+#endif // JSCell_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp
new file mode 100644
index 0000000..c8e137e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSFunction.h"
+
+#include "CodeBlock.h"
+#include "CommonIdentifiers.h"
+#include "CallFrame.h"
+#include "FunctionPrototype.h"
+#include "JSGlobalObject.h"
+#include "Interpreter.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", &InternalFunction::info, 0, 0 };
+
+JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
+ : Base(&exec->globalData(), structure, name)
+#if ENABLE(JIT)
+ , m_body(FunctionBodyNode::createNativeThunk(&exec->globalData()))
+#else
+ , m_body(0)
+#endif
+{
+#if ENABLE(JIT)
+ setNativeFunction(func);
+ putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+#else
+ UNUSED_PARAM(length);
+ UNUSED_PARAM(func);
+ ASSERT_NOT_REACHED();
+#endif
+}
+
+JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
+ : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
+ , m_body(body)
+{
+ setScopeChain(scopeChainNode);
+}
+
+JSFunction::~JSFunction()
+{
+#if ENABLE(JIT)
+ // JIT code for other functions may have had calls linked directly to the code for this function; these links
+ // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
+ // this memory is freed and may be reused (potentially for another, different JSFunction).
+ if (m_body && m_body->isGenerated())
+ m_body->generatedBytecode().unlinkCallers();
+#endif
+ if (!isHostFunction())
+ scopeChain().~ScopeChain();
+}
+
+void JSFunction::mark()
+{
+ Base::mark();
+ m_body->mark();
+ if (!isHostFunction())
+ scopeChain().mark();
+}
+
+CallType JSFunction::getCallData(CallData& callData)
+{
+ if (isHostFunction()) {
+ callData.native.function = nativeFunction();
+ return CallTypeHost;
+ }
+ callData.js.functionBody = m_body.get();
+ callData.js.scopeChain = scopeChain().node();
+ return CallTypeJS;
+}
+
+JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args)
+{
+ ASSERT(!isHostFunction());
+ return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
+}
+
+JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+ JSFunction* thisObj = asFunction(slot.slotBase());
+ ASSERT(!thisObj->isHostFunction());
+ return exec->interpreter()->retrieveArguments(exec, thisObj);
+}
+
+JSValue JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+ JSFunction* thisObj = asFunction(slot.slotBase());
+ ASSERT(!thisObj->isHostFunction());
+ return exec->interpreter()->retrieveCaller(exec, thisObj);
+}
+
+JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+ JSFunction* thisObj = asFunction(slot.slotBase());
+ ASSERT(!thisObj->isHostFunction());
+ return jsNumber(exec, thisObj->m_body->parameterCount());
+}
+
+bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ if (isHostFunction())
+ return Base::getOwnPropertySlot(exec, propertyName, slot);
+
+ if (propertyName == exec->propertyNames().prototype) {
+ JSValue* location = getDirectLocation(propertyName);
+
+ if (!location) {
+ JSObject* prototype = new (exec) JSObject(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 (isHostFunction()) {
+ Base::put(exec, propertyName, value, slot);
+ return;
+ }
+ if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+ return;
+ Base::put(exec, propertyName, value, slot);
+}
+
+bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+{
+ if (isHostFunction())
+ return Base::deleteProperty(exec, propertyName, checkDontDelete);
+ if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+ return false;
+ return Base::deleteProperty(exec, propertyName, checkDontDelete);
+}
+
+// ECMA 13.2.2 [[Construct]]
+ConstructType JSFunction::getConstructData(ConstructData& constructData)
+{
+ if (isHostFunction())
+ return ConstructTypeNone;
+ constructData.js.functionBody = m_body.get();
+ constructData.js.scopeChain = scopeChain().node();
+ return ConstructTypeJS;
+}
+
+JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
+{
+ ASSERT(!isHostFunction());
+ Structure* 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->interpreter()->execute(m_body.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
+ if (exec->hadException() || !result.isObject())
+ return thisObj;
+ return asObject(result);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h
new file mode 100644
index 0000000..5ddd97c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * 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 JIT;
+ friend class VPtrSet;
+
+ typedef InternalFunction Base;
+
+ JSFunction(PassRefPtr<Structure> structure)
+ : InternalFunction(structure)
+ {
+ clearScopeChain();
+ }
+
+ public:
+ JSFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
+ JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
+ ~JSFunction();
+
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
+
+ JSObject* construct(ExecState*, const ArgList&);
+ JSValue call(ExecState*, JSValue thisValue, const ArgList&);
+
+ void setScope(const ScopeChain& scopeChain) { setScopeChain(scopeChain); }
+ ScopeChain& scope() { return scopeChain(); }
+
+ void setBody(FunctionBodyNode* body) { m_body = body; }
+ void setBody(PassRefPtr<FunctionBodyNode> body) { m_body = body; }
+ FunctionBodyNode* body() const { return m_body.get(); }
+
+ virtual void mark();
+
+ static JS_EXPORTDATA const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+ }
+
+#if ENABLE(JIT)
+ bool isHostFunction() const { return m_body && m_body->isHostFunction(); }
+#else
+ bool isHostFunction() const { return false; }
+#endif
+ NativeFunction nativeFunction()
+ {
+ return *reinterpret_cast<NativeFunction*>(m_data);
+ }
+
+ virtual ConstructType getConstructData(ConstructData&);
+ virtual CallType getCallData(CallData&);
+
+ private:
+ virtual const ClassInfo* classInfo() const { return &info; }
+
+ static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValue callerGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
+
+ RefPtr<FunctionBodyNode> m_body;
+ ScopeChain& scopeChain()
+ {
+ ASSERT(!isHostFunction());
+ return *reinterpret_cast<ScopeChain*>(m_data);
+ }
+ void clearScopeChain()
+ {
+ ASSERT(!isHostFunction());
+ new (m_data) ScopeChain(NoScopeChain());
+ }
+ void setScopeChain(ScopeChainNode* sc)
+ {
+ ASSERT(!isHostFunction());
+ new (m_data) ScopeChain(sc);
+ }
+ void setScopeChain(const ScopeChain& sc)
+ {
+ ASSERT(!isHostFunction());
+ *reinterpret_cast<ScopeChain*>(m_data) = sc;
+ }
+ void setNativeFunction(NativeFunction func)
+ {
+ *reinterpret_cast<NativeFunction*>(m_data) = func;
+ }
+ unsigned char m_data[sizeof(void*)];
+ };
+
+ JSFunction* asFunction(JSValue);
+
+ inline JSFunction* asFunction(JSValue value)
+ {
+ ASSERT(asObject(value)->inherits(&JSFunction::info));
+ return static_cast<JSFunction*>(asObject(value));
+ }
+
+} // namespace JSC
+
+#endif // JSFunction_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp
new file mode 100644
index 0000000..85d881e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -0,0 +1,254 @@
+/*
+ * 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 "Collector.h"
+#include "CommonIdentifiers.h"
+#include "FunctionConstructor.h"
+#include "Interpreter.h"
+#include "JSActivation.h"
+#include "JSArray.h"
+#include "JSByteArray.h"
+#include "JSClassRef.h"
+#include "JSFunction.h"
+#include "JSLock.h"
+#include "JSNotAnObject.h"
+#include "JSStaticScopeObject.h"
+#include "Parser.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 JSC_CONST_HASHTABLE HashTable arrayTable;
+extern JSC_CONST_HASHTABLE HashTable jsonTable;
+extern JSC_CONST_HASHTABLE HashTable dateTable;
+extern JSC_CONST_HASHTABLE HashTable mathTable;
+extern JSC_CONST_HASHTABLE HashTable numberTable;
+extern JSC_CONST_HASHTABLE HashTable regExpTable;
+extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable;
+extern JSC_CONST_HASHTABLE HashTable stringTable;
+
+struct VPtrSet {
+ VPtrSet();
+
+ void* jsArrayVPtr;
+ void* jsByteArrayVPtr;
+ void* jsStringVPtr;
+ void* jsFunctionVPtr;
+};
+
+VPtrSet::VPtrSet()
+{
+ // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
+ void* storage = fastMalloc(sizeof(CollectorBlock));
+
+ JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
+ jsArrayVPtr = jsArray->vptr();
+ jsArray->~JSCell();
+
+ JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
+ jsByteArrayVPtr = jsByteArray->vptr();
+ jsByteArray->~JSCell();
+
+ JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
+ jsStringVPtr = jsString->vptr();
+ jsString->~JSCell();
+
+ JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
+ jsFunctionVPtr = jsFunction->vptr();
+ jsFunction->~JSCell();
+
+ fastFree(storage);
+}
+
+JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
+ : isSharedInstance(isShared)
+ , clientData(0)
+ , arrayTable(fastNew<HashTable>(JSC::arrayTable))
+ , dateTable(fastNew<HashTable>(JSC::dateTable))
+ , jsonTable(fastNew<HashTable>(JSC::jsonTable))
+ , mathTable(fastNew<HashTable>(JSC::mathTable))
+ , numberTable(fastNew<HashTable>(JSC::numberTable))
+ , regExpTable(fastNew<HashTable>(JSC::regExpTable))
+ , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
+ , stringTable(fastNew<HashTable>(JSC::stringTable))
+ , activationStructure(JSActivation::createStructure(jsNull()))
+ , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
+ , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
+ , stringStructure(JSString::createStructure(jsNull()))
+ , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
+ , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ , numberStructure(JSNumberCell::createStructure(jsNull()))
+#endif
+ , jsArrayVPtr(vptrSet.jsArrayVPtr)
+ , jsByteArrayVPtr(vptrSet.jsByteArrayVPtr)
+ , jsStringVPtr(vptrSet.jsStringVPtr)
+ , jsFunctionVPtr(vptrSet.jsFunctionVPtr)
+ , identifierTable(createIdentifierTable())
+ , propertyNames(new CommonIdentifiers(this))
+ , emptyList(new MarkedArgumentBuffer)
+ , lexer(new Lexer(this))
+ , parser(new Parser)
+ , interpreter(new Interpreter)
+#if ENABLE(JIT)
+ , jitStubs(this)
+#endif
+ , timeoutChecker(new TimeoutChecker)
+ , heap(this)
+ , initializingLazyNumericCompareFunction(false)
+ , head(0)
+ , dynamicGlobalObject(0)
+ , scopeNodeBeingReparsed(0)
+ , firstStringifierToMark(0)
+{
+#ifdef QT_BUILD_SCRIPT_LIB
+ scriptpool = new SourcePool();
+#endif
+#if PLATFORM(MAC)
+ startProfilerServerIfNeeded();
+#endif
+}
+
+JSGlobalData::~JSGlobalData()
+{
+ // By the time this is destroyed, heap.destroy() must already have been called.
+
+ delete interpreter;
+#ifndef NDEBUG
+ // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
+ interpreter = 0;
+#endif
+
+ arrayTable->deleteTable();
+ dateTable->deleteTable();
+ jsonTable->deleteTable();
+ mathTable->deleteTable();
+ numberTable->deleteTable();
+ regExpTable->deleteTable();
+ regExpConstructorTable->deleteTable();
+ stringTable->deleteTable();
+
+ fastDelete(const_cast<HashTable*>(arrayTable));
+ fastDelete(const_cast<HashTable*>(dateTable));
+ fastDelete(const_cast<HashTable*>(jsonTable));
+ fastDelete(const_cast<HashTable*>(mathTable));
+ fastDelete(const_cast<HashTable*>(numberTable));
+ fastDelete(const_cast<HashTable*>(regExpTable));
+ fastDelete(const_cast<HashTable*>(regExpConstructorTable));
+ fastDelete(const_cast<HashTable*>(stringTable));
+
+ delete parser;
+ delete lexer;
+ delete timeoutChecker;
+
+ deleteAllValues(opaqueJSClassData);
+
+ delete emptyList;
+
+ delete propertyNames;
+ deleteIdentifierTable(identifierTable);
+
+ delete clientData;
+#ifdef QT_BUILD_SCRIPT_LIB
+ if (scriptpool)
+ delete scriptpool;
+#endif
+}
+
+PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared)
+{
+ return adoptRef(new JSGlobalData(isShared, VPtrSet()));
+}
+
+PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
+{
+ Structure::startIgnoringLeaks();
+ RefPtr<JSGlobalData> data = create();
+ Structure::stopIgnoringLeaks();
+ return data.release();
+}
+
+bool JSGlobalData::sharedInstanceExists()
+{
+ return sharedInstanceInternal();
+}
+
+JSGlobalData& JSGlobalData::sharedInstance()
+{
+ JSGlobalData*& instance = sharedInstanceInternal();
+ if (!instance) {
+ instance = create(true).releaseRef();
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ instance->makeUsableFromMultipleThreads();
+#endif
+ }
+ return *instance;
+}
+
+JSGlobalData*& JSGlobalData::sharedInstanceInternal()
+{
+ ASSERT(JSLock::currentThreadIsHoldingLock());
+ static JSGlobalData* sharedInstance;
+ return sharedInstance;
+}
+
+// FIXME: We can also detect forms like v1 < v2 ? -1 : 0, reverse comparison, etc.
+const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec)
+{
+ if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
+ initializingLazyNumericCompareFunction = true;
+ RefPtr<ProgramNode> programNode = parser->parse<ProgramNode>(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
+ RefPtr<FunctionBodyNode> functionBody = extractFunctionBody(programNode.get());
+ lazyNumericCompareFunction = functionBody->bytecode(exec->scopeChain()).instructions();
+ initializingLazyNumericCompareFunction = false;
+ }
+
+ return lazyNumericCompareFunction;
+}
+
+JSGlobalData::ClientData::~ClientData()
+{
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h
new file mode 100644
index 0000000..fb557af
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * 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 "Collector.h"
+#include "ExecutableAllocator.h"
+#include "JITStubs.h"
+#include "JSValue.h"
+#include "SmallStrings.h"
+#include "TimeoutChecker.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+
+#ifdef QT_BUILD_SCRIPT_LIB
+#include "SourcePoolQt.h"
+#endif
+
+struct OpaqueJSClass;
+struct OpaqueJSClassContextData;
+
+namespace JSC {
+
+ class CommonIdentifiers;
+ class FunctionBodyNode;
+ class IdentifierTable;
+ class Instruction;
+ class Interpreter;
+ class JSGlobalObject;
+ class JSObject;
+ class Lexer;
+ class Parser;
+ class ScopeNode;
+ class Stringifier;
+ class Structure;
+ class UString;
+
+ struct HashTable;
+ struct VPtrSet;
+
+ class JSGlobalData : public RefCounted<JSGlobalData> {
+ public:
+ struct ClientData {
+ virtual ~ClientData() = 0;
+#ifdef QT_BUILD_SCRIPT_LIB
+ virtual void mark() {}
+#endif
+ };
+
+ static bool sharedInstanceExists();
+ static JSGlobalData& sharedInstance();
+
+ static PassRefPtr<JSGlobalData> create(bool isShared = false);
+ static PassRefPtr<JSGlobalData> createLeaked();
+ ~JSGlobalData();
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ // Will start tracking threads that use the heap, which is resource-heavy.
+ void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
+#endif
+
+ bool isSharedInstance;
+ ClientData* clientData;
+
+ const HashTable* arrayTable;
+ const HashTable* dateTable;
+ const HashTable* jsonTable;
+ const HashTable* mathTable;
+ const HashTable* numberTable;
+ const HashTable* regExpTable;
+ const HashTable* regExpConstructorTable;
+ const HashTable* stringTable;
+
+ RefPtr<Structure> activationStructure;
+ RefPtr<Structure> interruptedExecutionErrorStructure;
+ RefPtr<Structure> staticScopeStructure;
+ RefPtr<Structure> stringStructure;
+ RefPtr<Structure> notAnObjectErrorStubStructure;
+ RefPtr<Structure> notAnObjectStructure;
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ RefPtr<Structure> numberStructure;
+#endif
+
+ void* jsArrayVPtr;
+ void* jsByteArrayVPtr;
+ void* jsStringVPtr;
+ void* jsFunctionVPtr;
+
+ IdentifierTable* identifierTable;
+ CommonIdentifiers* propertyNames;
+ const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
+ SmallStrings smallStrings;
+
+#if ENABLE(ASSEMBLER)
+ ExecutableAllocator executableAllocator;
+#endif
+
+ Lexer* lexer;
+ Parser* parser;
+ Interpreter* interpreter;
+#ifdef QT_BUILD_SCRIPT_LIB
+ SourcePool* scriptpool;
+#endif
+#if ENABLE(JIT)
+ JITThunks jitStubs;
+#endif
+ TimeoutChecker* timeoutChecker;
+ Heap heap;
+
+ JSValue exception;
+#if ENABLE(JIT)
+ ReturnAddressPtr exceptionLocation;
+#endif
+
+ const Vector<Instruction>& numericCompareFunction(ExecState*);
+ Vector<Instruction> lazyNumericCompareFunction;
+ bool initializingLazyNumericCompareFunction;
+
+ HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
+
+ JSGlobalObject* head;
+ JSGlobalObject* dynamicGlobalObject;
+
+ HashSet<JSObject*> arrayVisitedElements;
+
+ ScopeNode* scopeNodeBeingReparsed;
+ Stringifier* firstStringifierToMark;
+
+ private:
+ JSGlobalData(bool isShared, const VPtrSet&);
+ static JSGlobalData*& sharedInstanceInternal();
+ void createNativeThunk();
+ };
+
+} // namespace JSC
+
+#endif // JSGlobalData_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp
new file mode 100644
index 0000000..55286d3
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSGlobalObject.h"
+
+#include "JSCallbackConstructor.h"
+#include "JSCallbackFunction.h"
+#include "JSCallbackObject.h"
+
+#include "Arguments.h"
+#include "ArrayConstructor.h"
+#include "ArrayPrototype.h"
+#include "BooleanConstructor.h"
+#include "BooleanPrototype.h"
+#include "CodeBlock.h"
+#include "DateConstructor.h"
+#include "DatePrototype.h"
+#include "ErrorConstructor.h"
+#include "ErrorPrototype.h"
+#include "FunctionConstructor.h"
+#include "FunctionPrototype.h"
+#include "GlobalEvalFunction.h"
+#include "JSFunction.h"
+#include "JSGlobalObjectFunctions.h"
+#include "JSLock.h"
+#include "JSONObject.h"
+#include "Interpreter.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<Structure>& 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)->clearGlobalObject();
+
+ RegisterFile& registerFile = globalData()->interpreter->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) {
+ JSValue valueAfter = getDirect(propertyName);
+ if (valueAfter)
+ JSObject::putWithAttributes(exec, 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::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
+ d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
+ NativeFunctionWrapper* callFunction = 0;
+ NativeFunctionWrapper* applyFunction = 0;
+ d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction);
+ d()->callFunction = callFunction;
+ d()->applyFunction = applyFunction;
+ d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get());
+ d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype);
+
+ d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
+
+ d()->functionStructure = JSFunction::createStructure(d()->functionPrototype);
+ d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype);
+ d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype);
+ d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype);
+ d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructure(d()->objectPrototype);
+
+ d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructure(d()->objectPrototype));
+ d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype);
+ d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype);
+
+ d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructure(d()->objectPrototype));
+ d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype);
+
+ d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype);
+
+ d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype);
+
+ d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructure(d()->objectPrototype));
+ d()->dateStructure = DateInstance::createStructure(d()->datePrototype);
+
+ d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype);
+
+ d()->methodCallDummy = constructEmptyObject(exec);
+
+ ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
+
+ RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(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
+
+ JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
+ JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
+ JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
+ JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
+ JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
+ JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
+ JSCell* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
+
+ d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype);
+
+ d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
+
+ RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(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->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
+ d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
+ d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
+ d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
+ d()->stringPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
+ d()->numberPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
+ d()->datePrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
+ d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
+ errorPrototype->putDirectFunctionWithoutTransition(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.
+
+ putDirectFunctionWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor, DontEnum);
+ putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor, DontEnum);
+
+ // Set global values.
+ GlobalPropertyInfo staticGlobals[] = {
+ GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructure(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),
+ GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
+ };
+
+ addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
+
+ // Set global functions.
+
+ d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructure(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
+ putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+#ifndef NDEBUG
+#ifndef QT_BUILD_SCRIPT_LIB
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
+#endif
+#endif
+
+ resetPrototype(prototype);
+}
+
+// Set prototype, and also insert the object prototype at the end of the chain.
+void JSGlobalObject::resetPrototype(JSValue prototype)
+{
+ setPrototype(prototype);
+
+ JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
+ JSObject* objectPrototype = d()->objectPrototype;
+ if (oldLastInPrototypeChain != objectPrototype)
+ oldLastInPrototypeChain->setPrototype(objectPrototype);
+}
+
+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()->interpreter->registerFile();
+ if (registerFile.globalObject() == this)
+ registerFile.markGlobals(&globalData()->heap);
+
+ markIfNeeded(d()->regExpConstructor);
+ markIfNeeded(d()->errorConstructor);
+ markIfNeeded(d()->evalErrorConstructor);
+ markIfNeeded(d()->rangeErrorConstructor);
+ markIfNeeded(d()->referenceErrorConstructor);
+ markIfNeeded(d()->syntaxErrorConstructor);
+ markIfNeeded(d()->typeErrorConstructor);
+ markIfNeeded(d()->URIErrorConstructor);
+
+ markIfNeeded(d()->evalFunction);
+ markIfNeeded(d()->callFunction);
+ markIfNeeded(d()->applyFunction);
+
+ markIfNeeded(d()->objectPrototype);
+ markIfNeeded(d()->functionPrototype);
+ markIfNeeded(d()->arrayPrototype);
+ markIfNeeded(d()->booleanPrototype);
+ markIfNeeded(d()->stringPrototype);
+ markIfNeeded(d()->numberPrototype);
+ markIfNeeded(d()->datePrototype);
+ markIfNeeded(d()->regExpPrototype);
+
+ markIfNeeded(d()->methodCallDummy);
+
+ markIfNeeded(d()->errorStructure);
+
+ // 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();
+ }
+}
+
+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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h
new file mode 100644
index 0000000..98e9b68
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSGlobalObject_h
+#define JSGlobalObject_h
+
+#include "JSGlobalData.h"
+#include "JSVariableObject.h"
+#include "NativeFunctionWrapper.h"
+#include "NumberPrototype.h"
+#include "StringPrototype.h"
+#include "StructureChain.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
+#ifdef QT_BUILD_SCRIPT_LIB
+#include "SourcePoolQt.h"
+#endif
+
+namespace JSC {
+
+ class ArrayPrototype;
+ class BooleanPrototype;
+ class DatePrototype;
+ class Debugger;
+ class ErrorConstructor;
+ class FunctionPrototype;
+ class GlobalEvalFunction;
+ class NativeErrorConstructor;
+ class ProgramCodeBlock;
+ class PrototypeFunction;
+ 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)
+ , callFunction(0)
+ , applyFunction(0)
+ , objectPrototype(0)
+ , functionPrototype(0)
+ , arrayPrototype(0)
+ , booleanPrototype(0)
+ , stringPrototype(0)
+ , numberPrototype(0)
+ , datePrototype(0)
+ , regExpPrototype(0)
+ , methodCallDummy(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;
+ NativeFunctionWrapper* callFunction;
+ NativeFunctionWrapper* applyFunction;
+
+ ObjectPrototype* objectPrototype;
+ FunctionPrototype* functionPrototype;
+ ArrayPrototype* arrayPrototype;
+ BooleanPrototype* booleanPrototype;
+ StringPrototype* stringPrototype;
+ NumberPrototype* numberPrototype;
+ DatePrototype* datePrototype;
+ RegExpPrototype* regExpPrototype;
+
+ JSObject* methodCallDummy;
+
+ RefPtr<Structure> argumentsStructure;
+ RefPtr<Structure> arrayStructure;
+ RefPtr<Structure> booleanObjectStructure;
+ RefPtr<Structure> callbackConstructorStructure;
+ RefPtr<Structure> callbackFunctionStructure;
+ RefPtr<Structure> callbackObjectStructure;
+ RefPtr<Structure> dateStructure;
+ RefPtr<Structure> emptyObjectStructure;
+ RefPtr<Structure> errorStructure;
+ RefPtr<Structure> functionStructure;
+ RefPtr<Structure> numberObjectStructure;
+ RefPtr<Structure> prototypeFunctionStructure;
+ RefPtr<Structure> regExpMatchesArrayStructure;
+ RefPtr<Structure> regExpStructure;
+ RefPtr<Structure> stringObjectStructure;
+
+ SymbolTable symbolTable;
+ unsigned profileGroup;
+
+ RefPtr<JSGlobalData> globalData;
+
+ HashSet<ProgramCodeBlock*> codeBlocks;
+ };
+
+ public:
+ void* operator new(size_t, JSGlobalData*);
+
+ explicit JSGlobalObject()
+ : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData)
+ {
+ init(this);
+ }
+
+ protected:
+ JSGlobalObject(PassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
+ : JSVariableObject(structure, data)
+ {
+ init(thisValue);
+ }
+
+ public:
+ virtual ~JSGlobalObject();
+
+ virtual void mark();
+
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+ virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
+ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+ virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes);
+
+ virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
+ virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
+
+ // 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; }
+
+ JSObject* methodCallDummy() const { return d()->methodCallDummy; }
+
+ Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
+ Structure* arrayStructure() const { return d()->arrayStructure.get(); }
+ Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
+ Structure* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
+ Structure* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
+ Structure* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
+ Structure* dateStructure() const { return d()->dateStructure.get(); }
+ Structure* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
+ Structure* errorStructure() const { return d()->errorStructure.get(); }
+ Structure* functionStructure() const { return d()->functionStructure.get(); }
+ Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
+ Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
+ Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
+ Structure* regExpStructure() const { return d()->regExpStructure.get(); }
+ Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
+
+ void setProfileGroup(unsigned value) { d()->profileGroup = value; }
+ unsigned profileGroup() const { return d()->profileGroup; }
+
+ Debugger* debugger() const { return d()->debugger; }
+ void setDebugger(Debugger* debugger)
+ {
+#ifdef QT_BUILD_SCRIPT_LIB
+ globalData()->scriptpool->setDebugger(debugger);
+#endif
+ 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 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<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::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::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName)
+ {
+ PropertySlot slot;
+ if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
+ return true;
+ bool slotIsWriteable;
+ 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 Structure::prototypeForLookup(ExecState* exec) const
+ {
+ if (typeInfo().type() == ObjectType)
+ return m_prototype;
+
+ if (typeInfo().type() == StringType)
+ return exec->lexicalGlobalObject()->stringPrototype();
+
+ ASSERT(typeInfo().type() == NumberType);
+ return exec->lexicalGlobalObject()->numberPrototype();
+ }
+
+ inline StructureChain* Structure::prototypeChain(ExecState* exec) const
+ {
+ // We cache our prototype chain so our clients can share it.
+ if (!isValid(exec, m_cachedPrototypeChain.get())) {
+ JSValue prototype = prototypeForLookup(exec);
+ m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure());
+ }
+ return m_cachedPrototypeChain.get();
+ }
+
+ inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const
+ {
+ if (!cachedPrototypeChain)
+ return false;
+
+ JSValue prototype = prototypeForLookup(exec);
+ RefPtr<Structure>* cachedStructure = cachedPrototypeChain->head();
+ while(*cachedStructure && !prototype.isNull()) {
+ if (asObject(prototype)->structure() != *cachedStructure)
+ return false;
+ ++cachedStructure;
+ prototype = asObject(prototype)->prototype();
+ }
+ return prototype.isNull() && !*cachedStructure;
+ }
+
+ 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;
+ }
+
+ class DynamicGlobalObjectScope : public Noncopyable {
+ public:
+ DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
+ , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
+ {
+ m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+ }
+
+ ~DynamicGlobalObjectScope()
+ {
+ m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
+ }
+
+ private:
+ JSGlobalObject*& m_dynamicGlobalObjectSlot;
+ JSGlobalObject* m_savedDynamicGlobalObject;
+ };
+
+} // namespace JSC
+
+#endif // JSGlobalObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
new file mode 100644
index 0000000..85f92f2
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSGlobalObjectFunctions.h"
+
+#include "CallFrame.h"
+#include "GlobalEvalFunction.h"
+#include "JSGlobalObject.h"
+#include "LiteralParser.h"
+#include "JSString.h"
+#include "Interpreter.h"
+#include "Parser.h"
+#include "dtoa.h"
+#include "Lexer.h"
+#include "Nodes.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(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(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 = WTF::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 JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObject = thisValue.toThisObject(exec);
+ JSObject* unwrappedObject = thisObject->unwrappedObject();
+ if (!unwrappedObject->isGlobalObject() || static_cast<JSGlobalObject*>(unwrappedObject)->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(0);
+ if (!x.isString())
+ return x;
+
+ UString s = x.toString(exec);
+
+ LiteralParser preparser(exec, s, LiteralParser::NonStrictJSON);
+ if (JSValue parsedObject = preparser.tryLiteralParse())
+ return parsedObject;
+
+ 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->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
+}
+
+JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ JSValue value = args.at(0);
+ int32_t radix = args.at(1).toInt32(exec);
+
+ if (value.isNumber() && (radix == 0 || radix == 10)) {
+ if (value.isInt32Fast())
+ return value;
+ double d = value.uncheckedGetNumber();
+ if (isfinite(d))
+ return jsNumber(exec, (d > 0) ? floor(d) : ceil(d));
+ if (isnan(d) || isinf(d))
+ return jsNaN(&exec->globalData());
+ return jsNumber(exec, 0);
+ }
+
+ return jsNumber(exec, parseInt(value.toString(exec), radix));
+}
+
+JSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, parseFloat(args.at(0).toString(exec)));
+}
+
+JSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsBoolean(isnan(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ double n = args.at(0).toNumber(exec);
+ return jsBoolean(!isnan(n) && !isinf(n));
+}
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return decode(exec, args, "", true);
+}
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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(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 JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ UString result = "";
+ UString str = args.at(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 (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) {
+ u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
+ c = &u;
+ k += 5;
+ }
+ } else if (c[0] == '%' && k <= len - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(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 JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ CStringBuffer string;
+ args.at(0).toString(exec).getCString(string);
+ puts(string.data());
+ return jsUndefined();
+}
+#endif
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
new file mode 100644
index 0000000..b1046f2
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * 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 <wtf/unicode/Unicode.h>
+
+namespace JSC {
+
+ class ArgList;
+ class ExecState;
+ class JSObject;
+ class JSValue;
+
+ // FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
+ // is a 0.5% reduction.
+
+ JSValue JSC_HOST_CALL globalFuncEval(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncParseInt(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncParseFloat(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncIsNaN(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncIsFinite(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncEscape(ExecState*, JSObject*, JSValue, const ArgList&);
+ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState*, JSObject*, JSValue, const ArgList&);
+#ifndef NDEBUG
+ JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState*, JSObject*, JSValue, const ArgList&);
+#endif
+
+ static const double mantissaOverflowLowerBound = 9007199254740992.0;
+ double parseIntOverflow(const char*, int length, int radix);
+ bool isStrWhiteSpace(UChar);
+
+} // namespace JSC
+
+#endif // JSGlobalObjectFunctions_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp
new file mode 100644
index 0000000..201e56c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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::toThisObject(JSValue v, ExecState* exec)
+{
+ ASSERT(isImmediate(v));
+ if (isNumber(v))
+ return constructNumber(exec, v);
+ if (isBoolean(v))
+ return constructBooleanFromImmediateBoolean(exec, v);
+ ASSERT(v.isUndefinedOrNull());
+ return exec->globalThisValue();
+}
+
+JSObject* JSImmediate::toObject(JSValue v, ExecState* exec)
+{
+ ASSERT(isImmediate(v));
+ if (isNumber(v))
+ return constructNumber(exec, v);
+ if (isBoolean(v))
+ return constructBooleanFromImmediateBoolean(exec, v);
+
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
+ exec->setException(exception);
+ return new (exec) JSNotAnObject(exec, exception);
+}
+
+JSObject* JSImmediate::prototype(JSValue v, ExecState* exec)
+{
+ ASSERT(isImmediate(v));
+ if (isNumber(v))
+ return exec->lexicalGlobalObject()->numberPrototype();
+ if (isBoolean(v))
+ return exec->lexicalGlobalObject()->booleanPrototype();
+
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
+ exec->setException(exception);
+ return new (exec) JSNotAnObject(exec, exception);
+}
+
+UString JSImmediate::toString(JSValue v)
+{
+ ASSERT(isImmediate(v));
+ if (isIntegerNumber(v))
+ return UString::from(getTruncatedInt32(v));
+#if USE(ALTERNATE_JSIMMEDIATE)
+ if (isNumber(v)) {
+ ASSERT(isDoubleNumber(v));
+ double value = doubleValue(v);
+ if (value == 0.0) // +0.0 or -0.0
+ return "0";
+ return UString::from(value);
+ }
+#else
+ ASSERT(!isNumber(v));
+#endif
+ if (jsBoolean(false) == v)
+ return "false";
+ if (jsBoolean(true) == v)
+ return "true";
+ if (v.isNull())
+ return "null";
+ ASSERT(v.isUndefined());
+ return "undefined";
+}
+
+NEVER_INLINE double JSImmediate::nonInlineNaN()
+{
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h
new file mode 100644
index 0000000..e7d7847
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSImmediate.h
@@ -0,0 +1,790 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSImmediate_h
+#define JSImmediate_h
+
+#include <wtf/Assertions.h>
+#include <wtf/AlwaysInline.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+#include "JSValue.h"
+#include <limits>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+namespace JSC {
+
+ class ExecState;
+ class JSCell;
+ class JSFastMath;
+ class JSGlobalData;
+ class JSObject;
+ class UString;
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ inline intptr_t reinterpretDoubleToIntptr(double value)
+ {
+ return WTF::bitwise_cast<intptr_t>(value);
+ }
+
+ inline double reinterpretIntptrToDouble(intptr_t value)
+ {
+ return WTF::bitwise_cast<double>(value);
+ }
+#endif
+
+ /*
+ * 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' ]
+ */
+
+ /*
+ * On 64-bit platforms, we support an alternative encoding form for immediates, if
+ * USE(ALTERNATE_JSIMMEDIATE) is defined. When this format is used, double precision
+ * floating point values may also be encoded as JSImmediates.
+ *
+ * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
+ * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
+ * can encode a 51-bit payload. Hardware produced and C-library payloads typically
+ * have a payload of zero. We assume that non-zero payloads are available to encode
+ * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
+ * all set represents a NaN with a non-zero payload, we can use this space in the NaN
+ * ranges to encode other values (however there are also other ranges of NaN space that
+ * could have been selected). This range of NaN space is represented by 64-bit numbers
+ * begining with the 16-bit hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no
+ * valid double-precision numbers will begin fall in these ranges.
+ *
+ * The scheme we have implemented encodes double precision values by adding 2^48 to the
+ * 64-bit integer representation of the number. After this manipulation, no encoded
+ * double-precision value will begin with the pattern 0x0000 or 0xFFFF.
+ *
+ * The top 16-bits denote the type of the encoded JSImmediate:
+ *
+ * Pointer: 0000:PPPP:PPPP:PPPP
+ * 0001:****:****:****
+ * Double:{ ...
+ * FFFE:****:****:****
+ * Integer: FFFF:0000:IIII:IIII
+ *
+ * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. The tag 0x0000
+ * denotes a pointer, or another form of tagged immediate. Boolean, null and undefined
+ * values are encoded in the same manner as the default format.
+ */
+
+ class JSImmediate {
+#ifdef QT_BUILD_SCRIPT_LIB
+ public: // QtScript needs isImmediate() and from() functions
+#else
+ private:
+#endif
+ friend class JIT;
+ friend class JSValue;
+ friend class JSFastMath;
+ friend JSValue jsNumber(ExecState* exec, double d);
+ friend JSValue jsNumber(ExecState*, char i);
+ friend JSValue jsNumber(ExecState*, unsigned char i);
+ friend JSValue jsNumber(ExecState*, short i);
+ friend JSValue jsNumber(ExecState*, unsigned short i);
+ friend JSValue jsNumber(ExecState* exec, int i);
+ friend JSValue jsNumber(ExecState* exec, unsigned i);
+ friend JSValue jsNumber(ExecState* exec, long i);
+ friend JSValue jsNumber(ExecState* exec, unsigned long i);
+ friend JSValue jsNumber(ExecState* exec, long long i);
+ friend JSValue jsNumber(ExecState* exec, unsigned long long i);
+ friend JSValue jsNumber(JSGlobalData* globalData, double d);
+ friend JSValue jsNumber(JSGlobalData* globalData, short i);
+ friend JSValue jsNumber(JSGlobalData* globalData, unsigned short i);
+ friend JSValue jsNumber(JSGlobalData* globalData, int i);
+ friend JSValue jsNumber(JSGlobalData* globalData, unsigned i);
+ friend JSValue jsNumber(JSGlobalData* globalData, long i);
+ friend JSValue jsNumber(JSGlobalData* globalData, unsigned long i);
+ friend JSValue jsNumber(JSGlobalData* globalData, long long i);
+ friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ // If all bits in the mask are set, this indicates an integer number,
+ // if any but not all are set this value is a double precision number.
+ static const intptr_t TagTypeNumber = 0xffff000000000000ll;
+ // This value is 2^48, used to encode doubles such that the encoded value will begin
+ // with a 16-bit pattern within the range 0x0001..0xFFFE.
+ static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
+#else
+ static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
+#endif
+ static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer
+ static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther;
+
+ static const intptr_t ExtendedTagMask = 0xC; // extended tag holds a further two bits
+ static const intptr_t ExtendedTagBitBool = 0x4;
+ static const intptr_t ExtendedTagBitUndefined = 0x8;
+
+ static const intptr_t FullTagTypeMask = TagMask | ExtendedTagMask;
+ static const intptr_t FullTagTypeBool = TagBitTypeOther | ExtendedTagBitBool;
+ static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
+ static const intptr_t FullTagTypeNull = TagBitTypeOther;
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static const int32_t IntegerPayloadShift = 0;
+#else
+ static const int32_t IntegerPayloadShift = 1;
+#endif
+ static const int32_t ExtendedPayloadShift = 4;
+
+ static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
+
+ static const int32_t signBit = 0x80000000;
+
+ static ALWAYS_INLINE bool isImmediate(JSValue v)
+ {
+ return rawValue(v) & TagMask;
+ }
+
+ static ALWAYS_INLINE bool isNumber(JSValue v)
+ {
+ return rawValue(v) & TagTypeNumber;
+ }
+
+ static ALWAYS_INLINE bool isIntegerNumber(JSValue v)
+ {
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
+#else
+ return isNumber(v);
+#endif
+ }
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE bool isDoubleNumber(JSValue v)
+ {
+ return isNumber(v) && !isIntegerNumber(v);
+ }
+#endif
+
+ static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValue v)
+ {
+ // A single mask to check for the sign bit and the number tag all at once.
+ return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber;
+ }
+
+ 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 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 areBothImmediate(JSValue v1, JSValue v2)
+ {
+ return isImmediate(v1) & isImmediate(v2);
+ }
+
+ static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
+ {
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
+#else
+ return rawValue(v1) & rawValue(v2) & TagTypeNumber;
+#endif
+ }
+
+ static double toDouble(JSValue);
+ static bool toBoolean(JSValue);
+ static JSObject* toObject(JSValue, ExecState*);
+ static JSObject* toThisObject(JSValue, ExecState*);
+ static UString toString(JSValue);
+
+ static bool getUInt32(JSValue, uint32_t&);
+ static bool getTruncatedInt32(JSValue, int32_t&);
+ 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 JSObject* prototype(JSValue, ExecState*);
+
+ private:
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static const int minImmediateInt = ((-INT_MAX) - 1);
+ static const int maxImmediateInt = INT_MAX;
+#else
+ static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
+ static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
+#endif
+ static const unsigned maxImmediateUInt = maxImmediateInt;
+
+ static ALWAYS_INLINE JSValue makeValue(intptr_t integer)
+ {
+ return JSValue::makeImmediate(integer);
+ }
+
+ // With USE(ALTERNATE_JSIMMEDIATE) we want the argument to be zero extended, so the
+ // integer doesn't interfere with the tag bits in the upper word. In the default encoding,
+ // if intptr_t id larger then int32_t we sign extend the value through the upper word.
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE JSValue makeInt(uint32_t value)
+#else
+ static ALWAYS_INLINE JSValue makeInt(int32_t value)
+#endif
+ {
+ return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber);
+ }
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE JSValue makeDouble(double value)
+ {
+ return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset);
+ }
+#endif
+
+ static ALWAYS_INLINE JSValue makeBool(bool b)
+ {
+ return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
+ }
+
+ static ALWAYS_INLINE JSValue makeUndefined()
+ {
+ return makeValue(FullTagTypeUndefined);
+ }
+
+ static ALWAYS_INLINE JSValue makeNull()
+ {
+ return makeValue(FullTagTypeNull);
+ }
+
+ template<typename T>
+ static JSValue fromNumberOutsideIntegerRange(T);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE double doubleValue(JSValue v)
+ {
+ return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset);
+ }
+#endif
+
+ static ALWAYS_INLINE int32_t intValue(JSValue v)
+ {
+ return static_cast<int32_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 intptr_t rawValue(JSValue v)
+ {
+ return v.immediateValue();
+ }
+
+ 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); }
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ inline bool doubleToBoolean(double value)
+ {
+ return value < 0.0 || value > 0.0;
+ }
+
+ ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
+ {
+ ASSERT(isImmediate(v));
+ return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate()
+ : doubleToBoolean(doubleValue(v)) : v == trueImmediate();
+ }
+#else
+ ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
+ {
+ ASSERT(isImmediate(v));
+ return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate();
+ }
+#endif
+
+ ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
+ {
+ // FIXME: should probably be asserting isPositiveIntegerNumber here.
+ ASSERT(isIntegerNumber(v));
+ return intValue(v);
+ }
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ template<typename T>
+ inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
+ {
+ return makeDouble(static_cast<double>(value));
+ }
+#else
+ template<typename T>
+ inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T)
+ {
+ return JSValue();
+ }
+#endif
+
+ 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 !USE(ALTERNATE_JSIMMEDIATE)
+ if ((i < minImmediateInt) | (i > maxImmediateInt))
+ return fromNumberOutsideIntegerRange(i);
+#endif
+ return makeInt(i);
+ }
+
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned i)
+ {
+ if (i > maxImmediateUInt)
+ return fromNumberOutsideIntegerRange(i);
+ return makeInt(i);
+ }
+
+ ALWAYS_INLINE JSValue JSImmediate::from(long i)
+ {
+ if ((i < minImmediateInt) | (i > maxImmediateInt))
+ return fromNumberOutsideIntegerRange(i);
+ return makeInt(i);
+ }
+
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned long i)
+ {
+ if (i > maxImmediateUInt)
+ return fromNumberOutsideIntegerRange(i);
+ return makeInt(i);
+ }
+
+ ALWAYS_INLINE JSValue JSImmediate::from(long long i)
+ {
+ if ((i < minImmediateInt) | (i > maxImmediateInt))
+ return JSValue();
+ return makeInt(static_cast<intptr_t>(i));
+ }
+
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned long long i)
+ {
+ if (i > maxImmediateUInt)
+ return fromNumberOutsideIntegerRange(i);
+ return makeInt(static_cast<intptr_t>(i));
+ }
+
+ ALWAYS_INLINE JSValue JSImmediate::from(double d)
+ {
+ const int intVal = static_cast<int>(d);
+
+ // Check for data loss from conversion to int.
+ if (intVal != d || (!intVal && signbit(d)))
+ return fromNumberOutsideIntegerRange(d);
+
+ return from(intVal);
+ }
+
+ ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue v)
+ {
+ ASSERT(isIntegerNumber(v));
+ return intValue(v);
+ }
+
+ ALWAYS_INLINE double JSImmediate::toDouble(JSValue v)
+ {
+ ASSERT(isImmediate(v));
+
+ if (isIntegerNumber(v))
+ return intValue(v);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ if (isNumber(v)) {
+ ASSERT(isDoubleNumber(v));
+ return doubleValue(v);
+ }
+#else
+ ASSERT(!isNumber(v));
+#endif
+
+ if (rawValue(v) == FullTagTypeUndefined)
+ return nonInlineNaN();
+
+ ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate()));
+ return rawValue(v) >> ExtendedPayloadShift;
+ }
+
+ ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue v, uint32_t& i)
+ {
+ i = uintValue(v);
+ return isPositiveIntegerNumber(v);
+ }
+
+ ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue v, int32_t& i)
+ {
+ i = intValue(v);
+ return isIntegerNumber(v);
+ }
+
+ ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue v, uint32_t& i)
+ {
+ return getUInt32(v, i);
+ }
+
+ // These are identical logic to the JSValue functions above, and faster than jsNumber(number).toInt32().
+ int32_t toInt32(double);
+ uint32_t toUInt32(double);
+ int32_t toInt32SlowCase(double, bool& ok);
+ uint32_t toUInt32SlowCase(double, bool& ok);
+
+ inline JSValue::JSValue(JSNullTag)
+ {
+ *this = JSImmediate::nullImmediate();
+ }
+
+ inline JSValue::JSValue(JSUndefinedTag)
+ {
+ *this = JSImmediate::undefinedImmediate();
+ }
+
+ inline JSValue::JSValue(JSTrueTag)
+ {
+ *this = JSImmediate::trueImmediate();
+ }
+
+ inline JSValue::JSValue(JSFalseTag)
+ {
+ *this = JSImmediate::falseImmediate();
+ }
+
+ 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 ignored;
+ return toInt32SlowCase(toNumber(exec), ignored);
+ }
+
+ inline uint32_t JSValue::toUInt32(ExecState* exec) const
+ {
+ uint32_t i;
+ if (getTruncatedUInt32(i))
+ return i;
+ bool ignored;
+ return toUInt32SlowCase(toNumber(exec), ignored);
+ }
+
+ inline int32_t toInt32(double val)
+ {
+ if (!(val >= -2147483648.0 && val < 2147483648.0)) {
+ bool ignored;
+ return toInt32SlowCase(val, ignored);
+ }
+ return static_cast<int32_t>(val);
+ }
+
+ inline uint32_t toUInt32(double val)
+ {
+ if (!(val >= 0.0 && val < 4294967296.0)) {
+ bool ignored;
+ return toUInt32SlowCase(val, ignored);
+ }
+ return static_cast<uint32_t>(val);
+ }
+
+ inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
+ {
+ int32_t i;
+ if (getTruncatedInt32(i)) {
+ ok = true;
+ return i;
+ }
+ return toInt32SlowCase(toNumber(exec), ok);
+ }
+
+ inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
+ {
+ uint32_t i;
+ if (getTruncatedUInt32(i)) {
+ ok = true;
+ return i;
+ }
+ return toUInt32SlowCase(toNumber(exec), ok);
+ }
+
+ inline bool JSValue::isCell() const
+ {
+ return !JSImmediate::isImmediate(asValue());
+ }
+
+ inline bool JSValue::isInt32Fast() const
+ {
+ return JSImmediate::isIntegerNumber(asValue());
+ }
+
+ inline int32_t JSValue::getInt32Fast() const
+ {
+ ASSERT(isInt32Fast());
+ return JSImmediate::getTruncatedInt32(asValue());
+ }
+
+ inline bool JSValue::isUInt32Fast() const
+ {
+ return JSImmediate::isPositiveIntegerNumber(asValue());
+ }
+
+ inline uint32_t JSValue::getUInt32Fast() const
+ {
+ ASSERT(isUInt32Fast());
+ return JSImmediate::getTruncatedUInt32(asValue());
+ }
+
+ inline JSValue JSValue::makeInt32Fast(int32_t i)
+ {
+ return JSImmediate::from(i);
+ }
+
+ inline bool JSValue::areBothInt32Fast(JSValue v1, JSValue v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
+ }
+
+ class JSFastMath {
+ public:
+ static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValue v1, JSValue v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
+ }
+
+ static ALWAYS_INLINE JSValue equal(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return jsBoolean(v1 == v2);
+ }
+
+ static ALWAYS_INLINE JSValue notEqual(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return jsBoolean(v1 != v2);
+ }
+
+ static ALWAYS_INLINE JSValue andImmediateNumbers(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2));
+ }
+
+ static ALWAYS_INLINE JSValue xorImmediateNumbers(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeNumber);
+ }
+
+ static ALWAYS_INLINE JSValue orImmediateNumbers(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2));
+ }
+
+ static ALWAYS_INLINE bool canDoFastRshift(JSValue v1, JSValue v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
+ }
+
+ static ALWAYS_INLINE bool canDoFastUrshift(JSValue v1, JSValue v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2) && !(JSImmediate::rawValue(v1) & JSImmediate::signBit);
+ }
+
+ static ALWAYS_INLINE JSValue rightShiftImmediateNumbers(JSValue val, JSValue shift)
+ {
+ ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);
+#else
+ return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber);
+#endif
+ }
+
+ 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 (JSImmediate::rawValue(v) & (JSImmediate::TagTypeNumber + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeNumber;
+ }
+
+ static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v1, JSValue v2)
+ {
+ // 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 canDoFastAdditiveOperations(v1) && canDoFastAdditiveOperations(v2);
+ }
+
+ static ALWAYS_INLINE JSValue addImmediateNumbers(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastAdditiveOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeNumber);
+ }
+
+ static ALWAYS_INLINE JSValue subImmediateNumbers(JSValue v1, JSValue v2)
+ {
+ ASSERT(canDoFastAdditiveOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeNumber);
+ }
+
+ static ALWAYS_INLINE JSValue incImmediateNumber(JSValue v)
+ {
+ ASSERT(canDoFastAdditiveOperations(v));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift));
+ }
+
+ static ALWAYS_INLINE JSValue decImmediateNumber(JSValue v)
+ {
+ ASSERT(canDoFastAdditiveOperations(v));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift));
+ }
+ };
+
+} // namespace JSC
+
+#endif // JSImmediate_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.cpp
new file mode 100644
index 0000000..8f056c8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.cpp
@@ -0,0 +1,254 @@
+/*
+ * 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 "CallFrame.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_lockBehavior(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+{
+ lock(m_lockBehavior);
+}
+
+void JSLock::lock(JSLockBehavior lockBehavior)
+{
+#ifdef NDEBUG
+ // Locking "not for real" is a debug-only feature.
+ if (lockBehavior == SilenceAssertionsOnly)
+ return;
+#endif
+
+ pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+ intptr_t currentLockCount = lockCount();
+ if (!currentLockCount && lockBehavior == LockForReal) {
+ int result;
+ result = pthread_mutex_lock(&JSMutex);
+ ASSERT(!result);
+ }
+ setLockCount(currentLockCount + 1);
+}
+
+void JSLock::unlock(JSLockBehavior lockBehavior)
+{
+ ASSERT(lockCount());
+
+#ifdef NDEBUG
+ // Locking "not for real" is a debug-only feature.
+ if (lockBehavior == SilenceAssertionsOnly)
+ return;
+#endif
+
+ intptr_t newLockCount = lockCount() - 1;
+ setLockCount(newLockCount);
+ if (!newLockCount && lockBehavior == LockForReal) {
+ int result;
+ result = pthread_mutex_unlock(&JSMutex);
+ ASSERT(!result);
+ }
+}
+
+void JSLock::lock(ExecState* exec)
+{
+ lock(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+}
+
+void JSLock::unlock(ExecState* exec)
+{
+ unlock(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+}
+
+bool JSLock::currentThreadIsHoldingLock()
+{
+ pthread_once(&createJSLockCountOnce, createJSLockCount);
+ return !!pthread_getspecific(JSLockCount);
+}
+
+// This is fairly nasty. We allow multiple threads to run on the same
+// context, and we do not require any locking semantics in doing so -
+// clients of the API may simply use the context from multiple threads
+// concurently, and assume this will work. In order to make this work,
+// We lock the context when a thread enters, and unlock it when it leaves.
+// However we do not only unlock when the thread returns from its
+// entry point (evaluate script or call function), we also unlock the
+// context if the thread leaves JSC by making a call out to an external
+// function through a callback.
+//
+// All threads using the context share the same JS stack (the RegisterFile).
+// Whenever a thread calls into JSC it starts using the RegisterFile from the
+// previous 'high water mark' - the maximum point the stack has ever grown to
+// (returned by RegisterFile::end()). So if a first thread calls out to a
+// callback, and a second thread enters JSC, then also exits by calling out
+// to a callback, we can be left with stackframes from both threads in the
+// RegisterFile. As such, a problem may occur should the first thread's
+// callback complete first, and attempt to return to JSC. Were we to allow
+// this to happen, and were its stack to grow further, then it may potentially
+// write over the second thread's call frames.
+//
+// In avoid JS stack corruption we enforce a policy of only ever allowing two
+// threads to use a JS context concurrently, and only allowing the second of
+// these threads to execute until it has completed and fully returned from its
+// outermost call into JSC. We enforce this policy using 'lockDropDepth'. The
+// first time a thread exits it will call DropAllLocks - which will do as expected
+// and drop locks allowing another thread to enter. Should another thread, or the
+// same thread again, enter JSC (through evaluate script or call function), and exit
+// again through a callback, then the locks will not be dropped when DropAllLocks
+// is called (since lockDropDepth is non-zero). Since this thread is still holding
+// the locks, only it will re able to re-enter JSC (either be returning from the
+// callback, or by re-entering through another call to evaulate script or call
+// function).
+//
+// This policy is slightly more restricive than it needs to be for correctness -
+// we could validly allow futher entries into JSC from other threads, we only
+// need ensure that callbacks return in the reverse chronological order of the
+// order in which they were made - though implementing the less restrictive policy
+// would likely increase complexity and overhead.
+//
+static unsigned lockDropDepth = 0;
+
+JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
+ : m_lockBehavior(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+{
+ pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+ if (lockDropDepth++) {
+ m_lockCount = 0;
+ return;
+ }
+
+ m_lockCount = JSLock::lockCount();
+ for (intptr_t i = 0; i < m_lockCount; i++)
+ JSLock::unlock(m_lockBehavior);
+}
+
+JSLock::DropAllLocks::DropAllLocks(JSLockBehavior JSLockBehavior)
+ : m_lockBehavior(JSLockBehavior)
+{
+ pthread_once(&createJSLockCountOnce, createJSLockCount);
+
+ if (lockDropDepth++) {
+ m_lockCount = 0;
+ return;
+ }
+
+ // 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_lockBehavior);
+}
+
+JSLock::DropAllLocks::~DropAllLocks()
+{
+ for (intptr_t i = 0; i < m_lockCount; i++)
+ JSLock::lock(m_lockBehavior);
+
+ --lockDropDepth;
+}
+
+#else
+
+JSLock::JSLock(ExecState*)
+ : m_lockBehavior(SilenceAssertionsOnly)
+{
+}
+
+// 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(JSLockBehavior)
+{
+}
+
+void JSLock::unlock(JSLockBehavior)
+{
+}
+
+void JSLock::lock(ExecState*)
+{
+}
+
+void JSLock::unlock(ExecState*)
+{
+}
+
+JSLock::DropAllLocks::DropAllLocks(ExecState*)
+{
+}
+
+JSLock::DropAllLocks::DropAllLocks(JSLockBehavior)
+{
+}
+
+JSLock::DropAllLocks::~DropAllLocks()
+{
+}
+
+#endif // USE(MULTIPLE_THREADS)
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.h
new file mode 100644
index 0000000..8b015c4
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSLock.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2005, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 JSLock_h
+#define 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;
+
+ enum JSLockBehavior { SilenceAssertionsOnly, LockForReal };
+
+ class JSLock : public Noncopyable {
+ public:
+ JSLock(ExecState*);
+
+ JSLock(JSLockBehavior lockBehavior)
+ : m_lockBehavior(lockBehavior)
+ {
+#ifdef NDEBUG
+ // Locking "not for real" is a debug-only feature.
+ if (lockBehavior == SilenceAssertionsOnly)
+ return;
+#endif
+ lock(lockBehavior);
+ }
+
+ ~JSLock()
+ {
+#ifdef NDEBUG
+ // Locking "not for real" is a debug-only feature.
+ if (m_lockBehavior == SilenceAssertionsOnly)
+ return;
+#endif
+ unlock(m_lockBehavior);
+ }
+
+ static void lock(JSLockBehavior);
+ static void unlock(JSLockBehavior);
+ static void lock(ExecState*);
+ static void unlock(ExecState*);
+
+ static intptr_t lockCount();
+ static bool currentThreadIsHoldingLock();
+
+ JSLockBehavior m_lockBehavior;
+
+ class DropAllLocks : public Noncopyable {
+ public:
+ DropAllLocks(ExecState* exec);
+ DropAllLocks(JSLockBehavior);
+ ~DropAllLocks();
+
+ private:
+ intptr_t m_lockCount;
+ JSLockBehavior m_lockBehavior;
+ };
+ };
+
+} // namespace
+
+#endif // JSLock_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp
new file mode 100644
index 0000000..fb9cfe8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return m_exception;
+}
+
+bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue&)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return false;
+}
+
+bool JSNotAnObject::toBoolean(ExecState* exec) const
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return false;
+}
+
+double JSNotAnObject::toNumber(ExecState* exec) const
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return NaN;
+}
+
+UString JSNotAnObject::toString(ExecState* exec) const
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return "";
+}
+
+JSObject* JSNotAnObject::toObject(ExecState* exec) const
+{
+ ASSERT_UNUSED(exec, 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&)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return false;
+}
+
+bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return false;
+}
+
+void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue, PutPropertySlot&)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+}
+
+void JSNotAnObject::put(ExecState* exec, unsigned, JSValue)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+}
+
+bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier&)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return false;
+}
+
+bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+ return false;
+}
+
+void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&, unsigned)
+{
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h
new file mode 100644
index 0000000..0aca63b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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 bytecodes -- 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<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::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&, unsigned listedAttributes = Structure::Prototype);
+
+ JSNotAnObjectErrorStub* m_exception;
+ };
+
+} // namespace JSC
+
+#endif // JSNotAnObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp
new file mode 100644
index 0000000..669440b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSNumberCell.h"
+
+#include "NumberObject.h"
+#include "UString.h"
+
+namespace JSC {
+
+#if !USE(ALTERNATE_JSIMMEDIATE)
+
+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;
+}
+
+JSValue jsNumberCell(ExecState* exec, double d)
+{
+ return new (exec) JSNumberCell(exec, d);
+}
+
+JSValue jsNumberCell(JSGlobalData* globalData, double d)
+{
+ return new (globalData) JSNumberCell(globalData, d);
+}
+
+JSValue jsAPIMangledNumber(ExecState* exec, double d)
+{
+ return new (exec) JSNumberCell(JSNumberCell::APIMangled, d);
+}
+
+#else
+
+JSValue jsNumberCell(ExecState*, double)
+{
+ ASSERT_NOT_REACHED();
+ return JSValue();
+}
+
+JSValue jsAPIMangledNumber(ExecState*, double)
+{
+ ASSERT_NOT_REACHED();
+ return JSValue();
+}
+
+#endif
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h
new file mode 100644
index 0000000..a35e210
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSNumberCell_h
+#define JSNumberCell_h
+
+#include "CallFrame.h"
+#include "JSCell.h"
+#include "JSImmediate.h"
+#include "Collector.h"
+#include "UString.h"
+#include <stddef.h> // for size_t
+
+namespace JSC {
+
+ extern const double NaN;
+ extern const double Inf;
+
+ JSValue jsNumberCell(ExecState*, double);
+ JSValue jsAPIMangledNumber(ExecState*, double);
+
+#if !USE(ALTERNATE_JSIMMEDIATE)
+
+ class Identifier;
+ class JSCell;
+ class JSObject;
+ class JSString;
+ class PropertySlot;
+
+ struct ClassInfo;
+ struct Instruction;
+
+ class JSNumberCell : public JSCell {
+ friend class JIT;
+ friend JSValue jsNumberCell(JSGlobalData*, double);
+ friend JSValue jsNumberCell(ExecState*, double);
+ friend JSValue jsAPIMangledNumber(ExecState*, double);
+ public:
+ double value() const { return m_value; }
+
+ 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();
+
+ static const uintptr_t JSAPIMangledMagicNumber = 0xbbadbeef;
+ bool isAPIMangledNumber() const { return m_structure == reinterpret_cast<Structure*>(JSAPIMangledMagicNumber); }
+
+ void* operator new(size_t size, ExecState* exec)
+ {
+ #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return exec->heap()->inlineAllocateNumber(size);
+ #else
+ return exec->heap()->allocateNumber(size);
+ #endif
+ }
+
+ void* operator new(size_t size, JSGlobalData* globalData)
+ {
+ #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return globalData->heap.inlineAllocateNumber(size);
+ #else
+ return globalData->heap.allocateNumber(size);
+ #endif
+ }
+
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
+
+ private:
+ JSNumberCell(JSGlobalData* globalData, double value)
+ : JSCell(globalData->numberStructure.get())
+ , m_value(value)
+ {
+ }
+
+ JSNumberCell(ExecState* exec, double value)
+ : JSCell(exec->globalData().numberStructure.get())
+ , m_value(value)
+ {
+ }
+
+ enum APIMangledTag { APIMangled };
+ JSNumberCell(APIMangledTag, double value)
+ : JSCell(reinterpret_cast<Structure*>(JSAPIMangledMagicNumber))
+ , m_value(value)
+ {
+ }
+
+ virtual bool getUInt32(uint32_t&) const;
+ virtual bool getTruncatedInt32(int32_t&) const;
+ virtual bool getTruncatedUInt32(uint32_t&) const;
+
+ double m_value;
+ };
+
+ JSValue jsNumberCell(JSGlobalData*, double);
+
+ inline bool isNumberCell(JSValue v)
+ {
+ return v.isCell() && v.asCell()->isNumber();
+ }
+
+ inline JSNumberCell* asNumberCell(JSValue v)
+ {
+ ASSERT(isNumberCell(v));
+ return static_cast<JSNumberCell*>(v.asCell());
+ }
+
+
+ inline JSValue::JSValue(ExecState* exec, double d)
+ {
+ JSValue v = JSImmediate::from(d);
+ *this = v ? v : jsNumberCell(exec, d);
+ }
+
+ inline JSValue::JSValue(ExecState* exec, int i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
+ }
+
+ inline JSValue::JSValue(ExecState* exec, unsigned i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
+ }
+
+ inline JSValue::JSValue(ExecState* exec, long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
+ }
+
+ inline JSValue::JSValue(ExecState* exec, unsigned long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
+ }
+
+ inline JSValue::JSValue(ExecState* exec, long long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
+ }
+
+ inline JSValue::JSValue(ExecState* exec, unsigned long long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, double d)
+ {
+ JSValue v = JSImmediate::from(d);
+ *this = v ? v : jsNumberCell(globalData, d);
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, int i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, unsigned long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, long long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ }
+
+ inline JSValue::JSValue(JSGlobalData* globalData, unsigned long long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ }
+
+ inline bool JSValue::isDoubleNumber() const
+ {
+ return isNumberCell(asValue());
+ }
+
+ inline double JSValue::getDoubleNumber() const
+ {
+ return asNumberCell(asValue())->value();
+ }
+
+ inline bool JSValue::isNumber() const
+ {
+ return JSImmediate::isNumber(asValue()) || isDoubleNumber();
+ }
+
+ inline double JSValue::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
+ }
+
+ inline bool JSValue::isAPIMangledNumber()
+ {
+ ASSERT(isNumber());
+ return JSImmediate::isImmediate(asValue()) ? false : asNumberCell(asValue())->isAPIMangledNumber();
+ }
+
+#else
+
+ inline JSValue::JSValue(ExecState*, double d)
+ {
+ JSValue v = JSImmediate::from(d);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(ExecState*, int i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(ExecState*, unsigned i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(ExecState*, long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(ExecState*, unsigned long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(ExecState*, long long i)
+ {
+ JSValue v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(ExecState*, unsigned long long i)
+ {
+ JSValue v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, double d)
+ {
+ JSValue v = JSImmediate::from(d);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, int i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, unsigned i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, unsigned long i)
+ {
+ JSValue v = JSImmediate::from(i);
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, long long i)
+ {
+ JSValue v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, unsigned long long i)
+ {
+ JSValue v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ *this = v;
+ }
+
+ inline bool JSValue::isDoubleNumber() const
+ {
+ return JSImmediate::isDoubleNumber(asValue());
+ }
+
+ inline double JSValue::getDoubleNumber() const
+ {
+ return JSImmediate::doubleValue(asValue());
+ }
+
+ inline bool JSValue::isNumber() const
+ {
+ return JSImmediate::isNumber(asValue());
+ }
+
+ inline double JSValue::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return JSImmediate::toDouble(asValue());
+ }
+
+#endif
+
+ inline JSValue::JSValue(ExecState*, char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(ExecState*, unsigned char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(ExecState*, short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(ExecState*, unsigned short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, unsigned char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue::JSValue(JSGlobalData*, unsigned short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
+ }
+
+ inline JSValue jsNaN(ExecState* exec)
+ {
+ return jsNumber(exec, NaN);
+ }
+
+ inline JSValue jsNaN(JSGlobalData* globalData)
+ {
+ return jsNumber(globalData, NaN);
+ }
+
+ // --- JSValue inlines ----------------------------
+
+ ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
+ {
+ return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
+ }
+
+ inline bool JSValue::getNumber(double &result) const
+ {
+ if (isInt32Fast())
+ result = getInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ result = getDoubleNumber();
+ else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
+ }
+
+ inline bool JSValue::numberToInt32(int32_t& arg)
+ {
+ if (isInt32Fast())
+ arg = getInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ arg = JSC::toInt32(getDoubleNumber());
+ else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
+ }
+
+ inline bool JSValue::numberToUInt32(uint32_t& arg)
+ {
+ if (isUInt32Fast())
+ arg = getUInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ arg = JSC::toUInt32(getDoubleNumber());
+ else if (isInt32Fast()) {
+ // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
+ // on a negative value is equivalent to simple static_casting.
+ bool ignored;
+ arg = toUInt32SlowCase(getInt32Fast(), ignored);
+ } else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
+ }
+
+} // namespace JSC
+
+#endif // JSNumberCell_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp
new file mode 100644
index 0000000..bbbe3af
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp
@@ -0,0 +1,766 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSONObject.h"
+
+#include "BooleanObject.h"
+#include "Error.h"
+#include "ExceptionHelpers.h"
+#include "JSArray.h"
+#include "LiteralParser.h"
+#include "PropertyNameArray.h"
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSONObject);
+
+static JSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*, JSObject*, JSValue, const ArgList&);
+
+}
+
+#include "JSONObject.lut.h"
+
+namespace JSC {
+
+// PropertyNameForFunctionCall objects must be on the stack, since the JSValue that they create is not marked.
+class PropertyNameForFunctionCall {
+public:
+ PropertyNameForFunctionCall(const Identifier&);
+ PropertyNameForFunctionCall(unsigned);
+
+ JSValue value(ExecState*) const;
+
+private:
+ const Identifier* m_identifier;
+ unsigned m_number;
+ mutable JSValue m_value;
+};
+
+class Stringifier : public Noncopyable {
+public:
+ Stringifier(ExecState*, JSValue replacer, JSValue space);
+ ~Stringifier();
+ JSValue stringify(JSValue);
+
+ void mark();
+
+private:
+ typedef UString StringBuilder;
+
+ class Holder {
+ public:
+ Holder(JSObject*);
+
+ JSObject* object() const { return m_object; }
+
+ bool appendNextProperty(Stringifier&, StringBuilder&);
+
+ private:
+ JSObject* const m_object;
+ const bool m_isArray;
+ bool m_isJSArray;
+ unsigned m_index;
+ unsigned m_size;
+ RefPtr<PropertyNameArrayData> m_propertyNames;
+ };
+
+ friend class Holder;
+
+ static void appendQuotedString(StringBuilder&, const UString&);
+
+ JSValue toJSON(JSValue, const PropertyNameForFunctionCall&);
+
+ enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue };
+ StringifyResult appendStringifiedValue(StringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&);
+
+ bool willIndent() const;
+ void indent();
+ void unindent();
+ void startNewLine(StringBuilder&) const;
+
+ Stringifier* const m_nextStringifierToMark;
+ ExecState* const m_exec;
+ const JSValue m_replacer;
+ bool m_usingArrayReplacer;
+ PropertyNameArray m_arrayReplacerPropertyNames;
+ CallType m_replacerCallType;
+ CallData m_replacerCallData;
+ const UString m_gap;
+
+ HashSet<JSObject*> m_holderCycleDetector;
+ Vector<Holder, 16> m_holderStack;
+ UString m_repeatedGap;
+ UString m_indent;
+};
+
+// ------------------------------ helper functions --------------------------------
+
+static inline JSValue unwrapBoxedPrimitive(JSValue value)
+{
+ if (!value.isObject())
+ return value;
+ if (!asObject(value)->inherits(&NumberObject::info) && !asObject(value)->inherits(&StringObject::info) && !asObject(value)->inherits(&BooleanObject::info))
+ return value;
+ return static_cast<JSWrapperObject*>(asObject(value))->internalValue();
+}
+
+static inline UString gap(JSValue space)
+{
+ space = unwrapBoxedPrimitive(space);
+
+ // If the space value is a number, create a gap string with that number of spaces.
+ double spaceCount;
+ if (space.getNumber(spaceCount)) {
+ const int maxSpaceCount = 100;
+ int count;
+ if (spaceCount > maxSpaceCount)
+ count = maxSpaceCount;
+ else if (!(spaceCount > 0))
+ count = 0;
+ else
+ count = static_cast<int>(spaceCount);
+ UChar spaces[maxSpaceCount];
+ for (int i = 0; i < count; ++i)
+ spaces[i] = ' ';
+ return UString(spaces, count);
+ }
+
+ // If the space value is a string, use it as the gap string, otherwise use no gap string.
+ return space.getString();
+}
+
+// ------------------------------ PropertyNameForFunctionCall --------------------------------
+
+inline PropertyNameForFunctionCall::PropertyNameForFunctionCall(const Identifier& identifier)
+ : m_identifier(&identifier)
+{
+}
+
+inline PropertyNameForFunctionCall::PropertyNameForFunctionCall(unsigned number)
+ : m_identifier(0)
+ , m_number(number)
+{
+}
+
+JSValue PropertyNameForFunctionCall::value(ExecState* exec) const
+{
+ if (!m_value) {
+ if (m_identifier)
+ m_value = jsString(exec, m_identifier->ustring());
+ else
+ m_value = jsNumber(exec, m_number);
+ }
+ return m_value;
+}
+
+// ------------------------------ Stringifier --------------------------------
+
+Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
+ : m_nextStringifierToMark(exec->globalData().firstStringifierToMark)
+ , m_exec(exec)
+ , m_replacer(replacer)
+ , m_usingArrayReplacer(false)
+ , m_arrayReplacerPropertyNames(exec)
+ , m_replacerCallType(CallTypeNone)
+ , m_gap(gap(space))
+{
+ exec->globalData().firstStringifierToMark = this;
+
+ if (!m_replacer.isObject())
+ return;
+
+ if (asObject(m_replacer)->inherits(&JSArray::info)) {
+ m_usingArrayReplacer = true;
+ JSObject* array = asObject(m_replacer);
+ unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
+ for (unsigned i = 0; i < length; ++i) {
+ JSValue name = array->get(exec, i);
+ if (exec->hadException())
+ break;
+ UString propertyName;
+ if (!name.getString(propertyName))
+ continue;
+ if (exec->hadException())
+ return;
+ m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName));
+ }
+ return;
+ }
+
+ m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData);
+}
+
+Stringifier::~Stringifier()
+{
+ ASSERT(m_exec->globalData().firstStringifierToMark == this);
+ m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark;
+}
+
+void Stringifier::mark()
+{
+ for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) {
+ size_t size = m_holderStack.size();
+ for (size_t i = 0; i < size; ++i) {
+ JSObject* object = m_holderStack[i].object();
+ if (!object->marked())
+ object->mark();
+ }
+ }
+}
+
+JSValue Stringifier::stringify(JSValue value)
+{
+ JSObject* object = constructEmptyObject(m_exec);
+ if (m_exec->hadException())
+ return jsNull();
+
+ PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
+ object->putDirect(m_exec->globalData().propertyNames->emptyIdentifier, value);
+
+ StringBuilder result;
+ if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
+ return jsUndefined();
+ if (m_exec->hadException())
+ return jsNull();
+
+ return jsString(m_exec, result);
+}
+
+void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
+{
+ int length = value.size();
+
+ // String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters.
+ builder.reserveCapacity(builder.size() + length + 2 + 8);
+
+ builder.append('"');
+
+ const UChar* data = value.data();
+ for (int i = 0; i < length; ++i) {
+ int start = i;
+ while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\'))
+ ++i;
+ builder.append(data + start, i - start);
+ if (i >= length)
+ break;
+ switch (data[i]) {
+ case '\t':
+ builder.append('\\');
+ builder.append('t');
+ break;
+ case '\r':
+ builder.append('\\');
+ builder.append('r');
+ break;
+ case '\n':
+ builder.append('\\');
+ builder.append('n');
+ break;
+ case '\f':
+ builder.append('\\');
+ builder.append('f');
+ break;
+ case '\b':
+ builder.append('\\');
+ builder.append('b');
+ break;
+ case '"':
+ builder.append('\\');
+ builder.append('"');
+ break;
+ case '\\':
+ builder.append('\\');
+ builder.append('\\');
+ break;
+ default:
+ static const char hexDigits[] = "0123456789abcdef";
+ UChar ch = data[i];
+ UChar hex[] = { '\\', 'u', hexDigits[(ch >> 12) & 0xF], hexDigits[(ch >> 8) & 0xF], hexDigits[(ch >> 4) & 0xF], hexDigits[ch & 0xF] };
+ builder.append(hex, sizeof(hex) / sizeof(UChar));
+ break;
+ }
+ }
+
+ builder.append('"');
+}
+
+inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName)
+{
+ ASSERT(!m_exec->hadException());
+ if (!value.isObject() || !asObject(value)->hasProperty(m_exec, m_exec->globalData().propertyNames->toJSON))
+ return value;
+
+ JSValue toJSONFunction = asObject(value)->get(m_exec, m_exec->globalData().propertyNames->toJSON);
+ if (m_exec->hadException())
+ return jsNull();
+
+ if (!toJSONFunction.isObject())
+ return value;
+
+ JSObject* object = asObject(toJSONFunction);
+ CallData callData;
+ CallType callType = object->getCallData(callData);
+ if (callType == CallTypeNone)
+ return value;
+
+ JSValue list[] = { propertyName.value(m_exec) };
+ ArgList args(list, sizeof(list) / sizeof(JSValue));
+ return call(m_exec, object, callType, callData, value, args);
+}
+
+Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName)
+{
+ // Call the toJSON function.
+ value = toJSON(value, propertyName);
+ if (m_exec->hadException())
+ return StringifyFailed;
+ if (value.isUndefined() && !holder->inherits(&JSArray::info))
+ return StringifyFailedDueToUndefinedValue;
+
+ // Call the replacer function.
+ if (m_replacerCallType != CallTypeNone) {
+ JSValue list[] = { propertyName.value(m_exec), value };
+ ArgList args(list, sizeof(list) / sizeof(JSValue));
+ value = call(m_exec, m_replacer, m_replacerCallType, m_replacerCallData, holder, args);
+ if (m_exec->hadException())
+ return StringifyFailed;
+ }
+
+ if (value.isNull()) {
+ builder.append("null");
+ return StringifySucceeded;
+ }
+
+ value = unwrapBoxedPrimitive(value);
+
+ if (value.isBoolean()) {
+ builder.append(value.getBoolean() ? "true" : "false");
+ return StringifySucceeded;
+ }
+
+ UString stringValue;
+ if (value.getString(stringValue)) {
+ appendQuotedString(builder, stringValue);
+ return StringifySucceeded;
+ }
+
+ double numericValue;
+ if (value.getNumber(numericValue)) {
+ if (!isfinite(numericValue))
+ builder.append("null");
+ else
+ builder.append(UString::from(numericValue));
+ return StringifySucceeded;
+ }
+
+ if (!value.isObject())
+ return StringifyFailed;
+
+ JSObject* object = asObject(value);
+
+ // Handle cycle detection, and put the holder on the stack.
+ if (!m_holderCycleDetector.add(object).second) {
+ throwError(m_exec, TypeError);
+ return StringifyFailed;
+ }
+ bool holderStackWasEmpty = m_holderStack.isEmpty();
+ m_holderStack.append(object);
+ if (!holderStackWasEmpty)
+ return StringifySucceeded;
+
+ // If this is the outermost call, then loop to handle everything on the holder stack.
+ TimeoutChecker localTimeoutChecker(*m_exec->globalData().timeoutChecker);
+ localTimeoutChecker.reset();
+ unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck();
+ do {
+ while (m_holderStack.last().appendNextProperty(*this, builder)) {
+ if (m_exec->hadException())
+ return StringifyFailed;
+ if (!--tickCount) {
+ if (localTimeoutChecker.didTimeOut(m_exec)) {
+ m_exec->setException(createInterruptedExecutionException(&m_exec->globalData()));
+ return StringifyFailed;
+ }
+ tickCount = localTimeoutChecker.ticksUntilNextCheck();
+ }
+ }
+ m_holderCycleDetector.remove(m_holderStack.last().object());
+ m_holderStack.removeLast();
+ } while (!m_holderStack.isEmpty());
+ return StringifySucceeded;
+}
+
+inline bool Stringifier::willIndent() const
+{
+ return !m_gap.isEmpty();
+}
+
+inline void Stringifier::indent()
+{
+ // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent.
+ int newSize = m_indent.size() + m_gap.size();
+ if (newSize > m_repeatedGap.size())
+ m_repeatedGap.append(m_gap);
+ ASSERT(newSize <= m_repeatedGap.size());
+ m_indent = m_repeatedGap.substr(0, newSize);
+}
+
+inline void Stringifier::unindent()
+{
+ ASSERT(m_indent.size() >= m_gap.size());
+ m_indent = m_repeatedGap.substr(0, m_indent.size() - m_gap.size());
+}
+
+inline void Stringifier::startNewLine(StringBuilder& builder) const
+{
+ if (m_gap.isEmpty())
+ return;
+ builder.append('\n');
+ builder.append(m_indent);
+}
+
+inline Stringifier::Holder::Holder(JSObject* object)
+ : m_object(object)
+ , m_isArray(object->inherits(&JSArray::info))
+ , m_index(0)
+{
+}
+
+bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBuilder& builder)
+{
+ ASSERT(m_index <= m_size);
+
+ ExecState* exec = stringifier.m_exec;
+
+ // First time through, initialize.
+ if (!m_index) {
+ if (m_isArray) {
+ m_isJSArray = isJSArray(&exec->globalData(), m_object);
+ m_size = m_object->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
+ builder.append('[');
+ } else {
+ if (stringifier.m_usingArrayReplacer)
+ m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data();
+ else {
+ PropertyNameArray objectPropertyNames(exec);
+ m_object->getPropertyNames(exec, objectPropertyNames);
+ m_propertyNames = objectPropertyNames.releaseData();
+ }
+ m_size = m_propertyNames->propertyNameVector().size();
+ builder.append('{');
+ }
+ stringifier.indent();
+ }
+
+ // Last time through, finish up and return false.
+ if (m_index == m_size) {
+ stringifier.unindent();
+ if (m_size && builder[builder.size() - 1] != '{')
+ stringifier.startNewLine(builder);
+ builder.append(m_isArray ? ']' : '}');
+ return false;
+ }
+
+ // Handle a single element of the array or object.
+ unsigned index = m_index++;
+ unsigned rollBackPoint = 0;
+ StringifyResult stringifyResult;
+ if (m_isArray) {
+ // Get the value.
+ JSValue value;
+ if (m_isJSArray && asArray(m_object)->canGetIndex(index))
+ value = asArray(m_object)->getIndex(index);
+ else {
+ PropertySlot slot(m_object);
+ if (!m_object->getOwnPropertySlot(exec, index, slot))
+ slot.setUndefined();
+ if (exec->hadException())
+ return false;
+ value = slot.getValue(exec, index);
+ }
+
+ // Append the separator string.
+ if (index)
+ builder.append(',');
+ stringifier.startNewLine(builder);
+
+ // Append the stringified value.
+ stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, index);
+ } else {
+ // Get the value.
+ PropertySlot slot(m_object);
+ Identifier& propertyName = m_propertyNames->propertyNameVector()[index];
+ if (!m_object->getOwnPropertySlot(exec, propertyName, slot))
+ return true;
+ JSValue value = slot.getValue(exec, propertyName);
+ if (exec->hadException())
+ return false;
+
+ rollBackPoint = builder.size();
+
+ // Append the separator string.
+ if (builder[rollBackPoint - 1] != '{')
+ builder.append(',');
+ stringifier.startNewLine(builder);
+
+ // Append the property name.
+ appendQuotedString(builder, propertyName.ustring());
+ builder.append(':');
+ if (stringifier.willIndent())
+ builder.append(' ');
+
+ // Append the stringified value.
+ stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, propertyName);
+ }
+
+ // From this point on, no access to the this pointer or to any members, because the
+ // Holder object may have moved if the call to stringify pushed a new Holder onto
+ // m_holderStack.
+
+ switch (stringifyResult) {
+ case StringifyFailed:
+ builder.append("null");
+ break;
+ case StringifySucceeded:
+ break;
+ case StringifyFailedDueToUndefinedValue:
+ // This only occurs when get an undefined value for an object property.
+ // In this case we don't want the separator and property name that we
+ // already appended, so roll back.
+ builder = builder.substr(0, rollBackPoint);
+ break;
+ }
+
+ return true;
+}
+
+// ------------------------------ JSONObject --------------------------------
+
+const ClassInfo JSONObject::info = { "JSON", 0, 0, ExecState::jsonTable };
+
+/* Source for JSONObject.lut.h
+@begin jsonTable
+ parse JSONProtoFuncParse DontEnum|Function 1
+ stringify JSONProtoFuncStringify DontEnum|Function 1
+@end
+*/
+
+// ECMA 15.8
+
+bool JSONObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ const HashEntry* entry = ExecState::jsonTable(exec)->entry(exec, propertyName);
+ if (!entry)
+ return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+
+ ASSERT(entry->attributes() & Function);
+ setUpStaticFunctionSlot(exec, entry, this, propertyName, slot);
+ return true;
+}
+
+void JSONObject::markStringifiers(Stringifier* stringifier)
+{
+ stringifier->mark();
+}
+
+class Walker {
+public:
+ Walker(ExecState* exec, JSObject* function, CallType callType, CallData callData)
+ : m_exec(exec)
+ , m_function(function)
+ , m_callType(callType)
+ , m_callData(callData)
+ {
+ }
+ JSValue walk(JSValue unfiltered);
+private:
+ JSValue callReviver(JSValue property, JSValue unfiltered)
+ {
+ JSValue args[] = { property, unfiltered };
+ ArgList argList(args, 2);
+ return call(m_exec, m_function, m_callType, m_callData, jsNull(), argList);
+ }
+
+ friend class Holder;
+
+ ExecState* m_exec;
+ JSObject* m_function;
+ CallType m_callType;
+ CallData m_callData;
+};
+
+enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
+ ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
+NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
+{
+ Vector<PropertyNameArray, 16> propertyStack;
+ Vector<uint32_t, 16> indexStack;
+ Vector<JSObject*, 16> objectStack;
+ Vector<JSArray*, 16> arrayStack;
+
+ Vector<WalkerState, 16> stateStack;
+ WalkerState state = StateUnknown;
+ JSValue inValue = unfiltered;
+ JSValue outValue = jsNull();
+ while (1) {
+ switch (state) {
+ arrayStartState:
+ case ArrayStartState: {
+ ASSERT(inValue.isObject());
+ ASSERT(isJSArray(&m_exec->globalData(), asObject(inValue)));
+ JSArray* array = asArray(inValue);
+ arrayStack.append(array);
+ indexStack.append(0);
+ // fallthrough
+ }
+ arrayStartVisitMember:
+ case ArrayStartVisitMember: {
+ JSArray* array = arrayStack.last();
+ uint32_t index = indexStack.last();
+ if (index == array->length()) {
+ outValue = array;
+ arrayStack.removeLast();
+ indexStack.removeLast();
+ break;
+ }
+ inValue = array->getIndex(index);
+ if (inValue.isObject()) {
+ stateStack.append(ArrayEndVisitMember);
+ goto stateUnknown;
+ } else
+ outValue = inValue;
+ // fallthrough
+ }
+ case ArrayEndVisitMember: {
+ JSArray* array = arrayStack.last();
+ array->setIndex(indexStack.last(), callReviver(jsString(m_exec, UString::from(indexStack.last())), outValue));
+ if (m_exec->hadException())
+ return jsNull();
+ indexStack.last()++;
+ goto arrayStartVisitMember;
+ }
+ objectStartState:
+ case ObjectStartState: {
+ ASSERT(inValue.isObject());
+ ASSERT(!isJSArray(&m_exec->globalData(), asObject(inValue)));
+ JSObject* object = asObject(inValue);
+ objectStack.append(object);
+ indexStack.append(0);
+ propertyStack.append(PropertyNameArray(m_exec));
+ object->getPropertyNames(m_exec, propertyStack.last());
+ // fallthrough
+ }
+ objectStartVisitMember:
+ case ObjectStartVisitMember: {
+ JSObject* object = objectStack.last();
+ uint32_t index = indexStack.last();
+ PropertyNameArray& properties = propertyStack.last();
+ if (index == properties.size()) {
+ outValue = object;
+ objectStack.removeLast();
+ indexStack.removeLast();
+ propertyStack.removeLast();
+ break;
+ }
+ PropertySlot slot;
+ object->getOwnPropertySlot(m_exec, properties[index], slot);
+ inValue = slot.getValue(m_exec, properties[index]);
+ ASSERT(!m_exec->hadException());
+ if (inValue.isObject()) {
+ stateStack.append(ObjectEndVisitMember);
+ goto stateUnknown;
+ } else
+ outValue = inValue;
+ // fallthrough
+ }
+ case ObjectEndVisitMember: {
+ JSObject* object = objectStack.last();
+ Identifier prop = propertyStack.last()[indexStack.last()];
+ PutPropertySlot slot;
+ object->put(m_exec, prop, callReviver(jsString(m_exec, prop.ustring()), outValue), slot);
+ if (m_exec->hadException())
+ return jsNull();
+ indexStack.last()++;
+ goto objectStartVisitMember;
+ }
+ stateUnknown:
+ case StateUnknown:
+ if (!inValue.isObject()) {
+ outValue = inValue;
+ break;
+ }
+ if (isJSArray(&m_exec->globalData(), asObject(inValue)))
+ goto arrayStartState;
+ goto objectStartState;
+ }
+ if (stateStack.isEmpty())
+ break;
+ state = stateStack.last();
+ stateStack.removeLast();
+ }
+ return callReviver(jsEmptyString(m_exec), outValue);
+}
+
+// ECMA-262 v5 15.12.2
+JSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ if (args.isEmpty())
+ return throwError(exec, GeneralError, "JSON.parse requires at least one parameter");
+ JSValue value = args.at(0);
+ UString source = value.toString(exec);
+ if (exec->hadException())
+ return jsNull();
+
+ LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON);
+ JSValue unfiltered = jsonParser.tryLiteralParse();
+ if (!unfiltered)
+ return throwError(exec, SyntaxError, "Unable to parse JSON string");
+
+ if (args.size() < 2)
+ return unfiltered;
+
+ JSValue function = args.at(1);
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return unfiltered;
+ return Walker(exec, asObject(function), callType, callData).walk(unfiltered);
+}
+
+// ECMA-262 v5 15.12.3
+JSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ if (args.isEmpty())
+ return throwError(exec, GeneralError, "No input to stringify");
+ JSValue value = args.at(0);
+ JSValue replacer = args.at(1);
+ JSValue space = args.at(2);
+ return Stringifier(exec, replacer, space).stringify(value);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h
new file mode 100644
index 0000000..8d5364a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSONObject_h
+#define JSONObject_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ class Stringifier;
+
+ class JSONObject : public JSObject {
+ public:
+ JSONObject(PassRefPtr<Structure> structure)
+ : JSObject(structure)
+ {
+ }
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+
+ static void markStringifiers(Stringifier*);
+
+ private:
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+} // namespace JSC
+
+#endif // JSONObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
new file mode 100644
index 0000000..ded842d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Eric Seidel (eric@webkit.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSObject.h"
+
+#include "DatePrototype.h"
+#include "ErrorConstructor.h"
+#include "GetterSetter.h"
+#include "JSGlobalObject.h"
+#include "NativeErrorConstructor.h"
+#include "ObjectPrototype.h"
+#include "PropertyNameArray.h"
+#include "Lookup.h"
+#include "Nodes.h"
+#include "Operations.h"
+#include <math.h>
+#include <wtf/Assertions.h>
+
+#define JSOBJECT_MARK_TRACING 0
+
+#if JSOBJECT_MARK_TRACING
+
+#define JSOBJECT_MARK_BEGIN() \
+ static int markStackDepth = 0; \
+ for (int i = 0; i < markStackDepth; i++) \
+ putchar('-'); \
+ printf("%s (%p)\n", className().UTF8String().c_str(), this); \
+ markStackDepth++; \
+
+#define JSOBJECT_MARK_END() \
+ markStackDepth--;
+
+#else // JSOBJECT_MARK_TRACING
+
+#define JSOBJECT_MARK_BEGIN()
+#define JSOBJECT_MARK_END()
+
+#endif // JSOBJECT_MARK_TRACING
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSObject);
+
+void JSObject::mark()
+{
+ JSOBJECT_MARK_BEGIN();
+
+ JSCell::mark();
+ m_structure->mark();
+
+ PropertyStorage storage = propertyStorage();
+
+ size_t storageSize = m_structure->propertyStorageSize();
+ for (size_t i = 0; i < storageSize; ++i) {
+ JSValue v = JSValue::decode(storage[i]);
+ if (!v.marked())
+ v.mark();
+ }
+
+ JSOBJECT_MARK_END();
+}
+
+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) {
+ // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
+ if (!value.isObject() && !value.isNull())
+ return;
+
+ JSValue nextPrototypeValue = value;
+ while (nextPrototypeValue && nextPrototypeValue.isObject()) {
+ JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject();
+ if (nextPrototype == this) {
+ throwError(exec, GeneralError, "cyclic __proto__ value");
+ return;
+ }
+ nextPrototypeValue = nextPrototype->prototype();
+ }
+
+ setPrototype(value);
+ return;
+ }
+
+ // Check if there are any setters or getters in the prototype chain
+ JSValue prototype;
+ for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
+ prototype = obj->prototype();
+ if (prototype.isNull()) {
+ putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
+ return;
+ }
+ }
+
+ unsigned attributes;
+ JSCell* specificValue;
+ if ((m_structure->get(propertyName, attributes, specificValue) != 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);
+ MarkedArgumentBuffer 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;
+ }
+
+ putDirectInternal(exec->globalData(), 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* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+ putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot);
+}
+
+void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+ putDirectInternal(exec->globalData(), 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, bool checkDontDelete)
+{
+ unsigned attributes;
+ JSCell* specificValue;
+ if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) {
+ if ((attributes & DontDelete) && checkDontDelete)
+ return false;
+ removeDirect(propertyName);
+ return true;
+ }
+
+ // Look in the static hashtable of properties
+ const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
+ if (entry && (entry->attributes() & DontDelete) && checkDontDelete)
+ 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, bool checkDontDelete)
+{
+ return deleteProperty(exec, Identifier::from(exec, propertyName), checkDontDelete);
+}
+
+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 JSValue();
+ 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())) {
+ JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
+ if (value)
+ return value;
+ value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
+ if (value)
+ return value;
+ } else {
+ JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
+ if (value)
+ return value;
+ value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
+ if (value)
+ 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_structure->hasGetterSetterProperties());
+ asGetterSetter(object)->setGetter(getterFunction);
+ return;
+ }
+
+ PutPropertySlot slot;
+ GetterSetter* getterSetter = new (exec) GetterSetter;
+ putDirectInternal(exec->globalData(), propertyName, getterSetter, Getter, true, slot);
+
+ // putDirect will change our Structure if we add a new property. For
+ // getters and setters, though, we also need to change our Structure
+ // if we override an existing non-getter or non-setter.
+ if (slot.type() != PutPropertySlot::NewProperty) {
+ if (!m_structure->isDictionary()) {
+ RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure);
+ setStructure(structure.release());
+ }
+ }
+
+ m_structure->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_structure->hasGetterSetterProperties());
+ asGetterSetter(object)->setSetter(setterFunction);
+ return;
+ }
+
+ PutPropertySlot slot;
+ GetterSetter* getterSetter = new (exec) GetterSetter;
+ putDirectInternal(exec->globalData(), propertyName, getterSetter, Setter, true, slot);
+
+ // putDirect will change our Structure if we add a new property. For
+ // getters and setters, though, we also need to change our Structure
+ // if we override an existing non-getter or non-setter.
+ if (slot.type() != PutPropertySlot::NewProperty) {
+ if (!m_structure->isDictionary()) {
+ RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure);
+ setStructure(structure.release());
+ }
+ }
+
+ m_structure->setHasGetterSetterProperties(true);
+ getterSetter->setSetter(setterFunction);
+}
+
+JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
+{
+ JSObject* object = this;
+ while (true) {
+ if (JSValue value = object->getDirect(propertyName)) {
+ 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) {
+ if (JSValue value = object->getDirect(propertyName)) {
+ 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 (!value.isObject())
+ return false;
+
+ if (!proto.isObject()) {
+ throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
+ return false;
+ }
+
+ JSObject* object = asObject(value);
+ while ((object = object->prototype().getObject())) {
+ if (proto == object)
+ 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
+{
+ JSCell* specificValue;
+ if (m_structure->get(propertyName, attributes, specificValue) != 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;
+}
+
+bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyName, JSCell*& specificValue) const
+{
+ unsigned attributes;
+ if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
+ return true;
+
+ // This could be a function within the static table? - should probably
+ // also look in the hash? This currently should not be a problem, since
+ // we've currently always call 'get' first, which should have populated
+ // the normal storage.
+ return false;
+}
+
+void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes)
+{
+ m_structure->getPropertyNames(exec, propertyNames, this, listedAttributes);
+}
+
+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);
+}
+
+JSObject* JSObject::unwrappedObject()
+{
+ return this;
+}
+
+void JSObject::removeDirect(const Identifier& propertyName)
+{
+ size_t offset;
+ if (m_structure->isDictionary()) {
+ offset = m_structure->removePropertyWithoutTransition(propertyName);
+ if (offset != WTF::notFound)
+ putDirectOffset(offset, jsUndefined());
+ return;
+ }
+
+ RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
+ setStructure(structure.release());
+ if (offset != WTF::notFound)
+ putDirectOffset(offset, jsUndefined());
+}
+
+void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
+{
+ putDirectFunction(Identifier(exec, function->name(&exec->globalData())), function, attr);
+}
+
+void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
+{
+ putDirectFunctionWithoutTransition(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();
+}
+
+Structure* JSObject::createInheritorID()
+{
+#ifdef QT_BUILD_SCRIPT_LIB
+ // ### QtScript needs the hasOwnProperty() calls etc. for QScriptObject
+ m_inheritorID = Structure::create(this, TypeInfo(ObjectType, ImplementsHasInstance));
+#else
+ m_inheritorID = JSObject::createStructure(this);
+#endif
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h
new file mode 100644
index 0000000..15b7957
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h
@@ -0,0 +1,629 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSObject_h
+#define JSObject_h
+
+#include "ArgList.h"
+#include "ClassInfo.h"
+#include "CommonIdentifiers.h"
+#include "CallFrame.h"
+#include "JSNumberCell.h"
+#include "PropertySlot.h"
+#include "PutPropertySlot.h"
+#include "ScopeChain.h"
+#include "Structure.h"
+#include "JSGlobalData.h"
+
+namespace JSC {
+
+ inline JSCell* getJSFunction(JSGlobalData& globalData, JSValue value)
+ {
+ if (value.isCell() && (value.asCell()->vptr() == globalData.jsFunctionVPtr))
+ return value.asCell();
+ return 0;
+ }
+
+ class InternalFunction;
+ class PropertyNameArray;
+ class Structure;
+ 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
+ Getter = 1 << 5, // property is a getter
+ Setter = 1 << 6 // property is a setter
+ };
+
+ typedef EncodedJSValue* PropertyStorage;
+ typedef const EncodedJSValue* ConstPropertyStorage;
+
+ class JSObject : public JSCell {
+ friend class BatchedTransitionOptimizer;
+ friend class JIT;
+ friend class JSCell;
+
+ public:
+ explicit JSObject(PassRefPtr<Structure>);
+
+ 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 setStructure(PassRefPtr<Structure>);
+ Structure* inheritorID();
+
+ 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, bool checkReadOnly, PutPropertySlot& slot);
+ 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, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
+
+ virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
+
+ virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty);
+ virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype);
+
+ 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 JSObject* unwrappedObject();
+
+ virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+ bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
+
+ // This get function only looks at the property map.
+ JSValue getDirect(const Identifier& propertyName) const
+ {
+ size_t offset = m_structure->get(propertyName);
+ return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
+ }
+
+ JSValue* getDirectLocation(const Identifier& propertyName)
+ {
+ size_t offset = m_structure->get(propertyName);
+ return offset != WTF::notFound ? locationForOffset(offset) : 0;
+ }
+
+ JSValue* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+ {
+ JSCell* specificFunction;
+ size_t offset = m_structure->get(propertyName, attributes, specificFunction);
+ return offset != WTF::notFound ? locationForOffset(offset) : 0;
+ }
+
+ size_t offsetForLocation(JSValue* location) const
+ {
+ return location - reinterpret_cast<const JSValue*>(propertyStorage());
+ }
+
+ void transitionTo(Structure*);
+
+ void removeDirect(const Identifier& propertyName);
+ bool hasCustomProperties() { return !m_structure->isEmpty(); }
+ bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
+
+ void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
+
+ void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
+ void putDirectFunction(const Identifier& propertyName, JSCell* 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(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
+ void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
+
+ // Fast access to known property offsets.
+ JSValue getDirectOffset(size_t offset) const { return JSValue::decode(propertyStorage()[offset]); }
+ void putDirectOffset(size_t offset, JSValue value) { propertyStorage()[offset] = JSValue::encode(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 isActivationObject() 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 isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
+
+ static const size_t inlineStorageCapacity = 3;
+ static const size_t nonInlineBaseStorageCapacity = 16;
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ }
+
+ private:
+ ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
+ PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
+
+ const JSValue* locationForOffset(size_t offset) const
+ {
+ return reinterpret_cast<const JSValue*>(&propertyStorage()[offset]);
+ }
+
+ JSValue* locationForOffset(size_t offset)
+ {
+ return reinterpret_cast<JSValue*>(&propertyStorage()[offset]);
+ }
+
+ void putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
+ void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0);
+
+ bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+
+ const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
+ Structure* createInheritorID();
+
+ RefPtr<Structure> m_inheritorID;
+
+ union {
+ PropertyStorage m_externalStorage;
+ EncodedJSValue m_inlineStorage[inlineStorageCapacity];
+ };
+ };
+
+ JSObject* asObject(JSValue);
+
+ JSObject* constructEmptyObject(ExecState*);
+
+inline JSObject* asObject(JSValue value)
+{
+ ASSERT(asCell(value)->isObject());
+ return static_cast<JSObject*>(asCell(value));
+}
+
+inline JSObject::JSObject(PassRefPtr<Structure> structure)
+ : JSCell(structure.releaseRef()) // ~JSObject balances this ref()
+{
+ ASSERT(m_structure);
+ ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
+ ASSERT(m_structure->isEmpty());
+ ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
+}
+
+inline JSObject::~JSObject()
+{
+ ASSERT(m_structure);
+ if (!isUsingInlineStorage())
+ delete [] m_externalStorage;
+ m_structure->deref();
+}
+
+inline JSValue JSObject::prototype() const
+{
+ return m_structure->storedPrototype();
+}
+
+inline void JSObject::setPrototype(JSValue prototype)
+{
+ ASSERT(prototype);
+ RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
+ setStructure(newStructure.release());
+}
+
+inline void JSObject::setStructure(PassRefPtr<Structure> structure)
+{
+ m_structure->deref();
+ m_structure = structure.releaseRef(); // ~JSObject balances this ref()
+}
+
+inline Structure* JSObject::inheritorID()
+{
+ if (m_inheritorID)
+ return m_inheritorID.get();
+ return createInheritorID();
+}
+
+inline bool Structure::isUsingInlineStorage() const
+{
+ return (propertyStorageCapacity() == JSObject::inlineStorageCapacity);
+}
+
+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 isCell() && asCell()->isObject(classInfo);
+}
+
+ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ if (JSValue* location = getDirectLocation(propertyName)) {
+ if (m_structure->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;
+}
+
+// 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 (structure()->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::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
+{
+ ASSERT(value);
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+ if (m_structure->isDictionary()) {
+ unsigned currentAttributes;
+ JSCell* currentSpecificFunction;
+ size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
+ if (offset != WTF::notFound) {
+ if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
+ m_structure->despecifyDictionaryFunction(propertyName);
+ if (checkReadOnly && currentAttributes & ReadOnly)
+ return;
+ putDirectOffset(offset, value);
+ if (!specificFunction && !currentSpecificFunction)
+ slot.setExistingProperty(this, offset);
+ return;
+ }
+
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction);
+ if (currentCapacity != m_structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+
+ ASSERT(offset < m_structure->propertyStorageCapacity());
+ putDirectOffset(offset, value);
+ // See comment on setNewProperty call below.
+ if (!specificFunction)
+ slot.setNewProperty(this, offset);
+ return;
+ }
+
+ size_t offset;
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) {
+ if (currentCapacity != structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
+
+ ASSERT(offset < structure->propertyStorageCapacity());
+ setStructure(structure.release());
+ putDirectOffset(offset, value);
+ // See comment on setNewProperty call below.
+ if (!specificFunction)
+ slot.setNewProperty(this, offset);
+ return;
+ }
+
+ unsigned currentAttributes;
+ JSCell* currentSpecificFunction;
+ offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
+ if (offset != WTF::notFound) {
+ if (checkReadOnly && currentAttributes & ReadOnly)
+ return;
+
+ if (currentSpecificFunction && (specificFunction != currentSpecificFunction)) {
+ setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
+ putDirectOffset(offset, value);
+ // Function transitions are not currently cachable, so leave the slot in an uncachable state.
+ return;
+ }
+ putDirectOffset(offset, value);
+ slot.setExistingProperty(this, offset);
+ return;
+ }
+
+ RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset);
+ if (currentCapacity != structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
+
+ ASSERT(offset < structure->propertyStorageCapacity());
+ setStructure(structure.release());
+ putDirectOffset(offset, value);
+ // Function transitions are not currently cachable, so leave the slot in an uncachable state.
+ if (!specificFunction)
+ slot.setNewProperty(this, offset);
+}
+
+inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+ ASSERT(value);
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+ putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
+}
+
+inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+ PutPropertySlot slot;
+ putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
+}
+
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+ ASSERT(value);
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+ putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
+}
+
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+ PutPropertySlot slot;
+ putDirectInternal(propertyName, value, attributes, false, slot, 0);
+}
+
+inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+ putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, value);
+}
+
+inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr)
+{
+ PutPropertySlot slot;
+ putDirectInternal(propertyName, value, attr, false, slot, value);
+}
+
+inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, 0);
+ if (currentCapacity != m_structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+ putDirectOffset(offset, value);
+}
+
+inline void JSObject::putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attributes)
+{
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value);
+ if (currentCapacity != m_structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+ putDirectOffset(offset, value);
+}
+
+inline void JSObject::transitionTo(Structure* newStructure)
+{
+ if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
+ allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
+ setStructure(newStructure);
+}
+
+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(asValue());
+ return get(exec, propertyName, slot);
+}
+
+inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
+{
+ if (UNLIKELY(!isCell())) {
+ JSObject* prototype = JSImmediate::prototype(asValue(), exec);
+ if (propertyName == exec->propertyNames().underscoreProto)
+ return prototype;
+ 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(asValue());
+ return get(exec, propertyName, slot);
+}
+
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
+{
+ if (UNLIKELY(!isCell())) {
+ 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(!isCell())) {
+ 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(!isCell())) {
+ 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);
+
+ // It's important that this function not rely on m_structure, since
+ // we might be in the middle of a transition.
+ bool wasInline = (oldSize == JSObject::inlineStorageCapacity);
+
+ PropertyStorage oldPropertyStorage = (wasInline ? m_inlineStorage : m_externalStorage);
+ PropertyStorage newPropertyStorage = new EncodedJSValue[newSize];
+
+ for (unsigned i = 0; i < oldSize; ++i)
+ newPropertyStorage[i] = oldPropertyStorage[i];
+
+ if (!wasInline)
+ delete [] oldPropertyStorage;
+
+ m_externalStorage = newPropertyStorage;
+}
+
+} // namespace JSC
+
+#endif // JSObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
new file mode 100644
index 0000000..8c7b53d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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 JSValue();
+}
+
+bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue&)
+{
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+bool JSPropertyNameIterator::toBoolean(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+double JSPropertyNameIterator::toNumber(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+UString JSPropertyNameIterator::toString(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+JSObject* JSPropertyNameIterator::toObject(ExecState*) const
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void JSPropertyNameIterator::mark()
+{
+ JSCell::mark();
+ if (m_object && !m_object->marked())
+ m_object->mark();
+}
+
+void JSPropertyNameIterator::invalidate()
+{
+ ASSERT(m_position == m_end);
+ m_object = 0;
+ m_data.clear();
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h
new file mode 100644
index 0000000..9817c07
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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 JSValue();
+
+ if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec))
+ return jsOwnedString(exec, (*m_position++).ustring());
+
+ do {
+ if (m_object->hasProperty(exec, *m_position))
+ return jsOwnedString(exec, (*m_position++).ustring());
+ m_position++;
+ } while (m_position != m_end);
+
+ return JSValue();
+}
+
+} // namespace JSC
+
+#endif // JSPropertyNameIterator_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp
new file mode 100644
index 0000000..85907c8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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);
+}
+
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h
new file mode 100644
index 0000000..2caf540
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -0,0 +1,68 @@
+/*
+ * 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().staticScopeStructure, 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 void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+ void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
+
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+
+ private:
+ JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
+ };
+
+}
+
+#endif // JSStaticScopeObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp
new file mode 100644
index 0000000..e1fc66d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSString.h"
+
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+#include "StringObject.h"
+#include "StringPrototype.h"
+
+namespace JSC {
+
+JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+ return const_cast<JSString*>(this);
+}
+
+bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
+{
+ value = this;
+ number = m_value.toDouble();
+ return false;
+}
+
+bool JSString::toBoolean(ExecState*) const
+{
+ return !m_value.isEmpty();
+}
+
+double JSString::toNumber(ExecState*) const
+{
+ return m_value.toDouble();
+}
+
+UString JSString::toString(ExecState*) const
+{
+ return m_value;
+}
+
+UString JSString::toThisString(ExecState*) const
+{
+ return m_value;
+}
+
+JSString* JSString::toThisJSString(ExecState*)
+{
+ return this;
+}
+
+inline StringObject* StringObject::create(ExecState* exec, JSString* string)
+{
+ return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
+}
+
+JSObject* JSString::toObject(ExecState* exec) const
+{
+ return StringObject::create(exec, const_cast<JSString*>(this));
+}
+
+JSObject* JSString::toThisObject(ExecState* exec) const
+{
+ return StringObject::create(exec, const_cast<JSString*>(this));
+}
+
+bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ // The semantics here are really getPropertySlot, not getOwnPropertySlot.
+ // This function should only be called by JSValue::get.
+ if (getStringPropertySlot(exec, propertyName, slot))
+ return true;
+ if (propertyName == exec->propertyNames().underscoreProto) {
+ slot.setValue(exec->lexicalGlobalObject()->stringPrototype());
+ 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);
+}
+
+bool JSString::getStringPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+{
+ if (propertyName == exec->propertyNames().length) {
+ attributes = DontEnum | DontDelete | ReadOnly;
+ return true;
+ }
+ bool isStrictUInt32;
+ unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
+ if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
+ attributes = DontDelete | ReadOnly;
+ return true;
+ }
+ return false;
+}
+
+JSString* jsString(JSGlobalData* globalData, const UString& s)
+{
+ int size = s.size();
+ if (!size)
+ return globalData->smallStrings.emptyString(globalData);
+ if (size == 1) {
+ UChar c = s.data()[0];
+ if (c <= 0xFF)
+ return globalData->smallStrings.singleCharacterString(globalData, c);
+ }
+ return new (globalData) JSString(globalData, s);
+}
+
+JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)
+{
+ ASSERT(offset <= static_cast<unsigned>(s.size()));
+ ASSERT(length <= static_cast<unsigned>(s.size()));
+ ASSERT(offset + length <= static_cast<unsigned>(s.size()));
+ if (!length)
+ return globalData->smallStrings.emptyString(globalData);
+ if (length == 1) {
+ UChar c = s.data()[offset];
+ if (c <= 0xFF)
+ return globalData->smallStrings.singleCharacterString(globalData, c);
+ }
+ return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length));
+}
+
+JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
+{
+ int size = s.size();
+ if (!size)
+ return globalData->smallStrings.emptyString(globalData);
+ if (size == 1) {
+ UChar c = s.data()[0];
+ if (c <= 0xFF)
+ return globalData->smallStrings.singleCharacterString(globalData, c);
+ }
+ return new (globalData) JSString(globalData, s, JSString::HasOtherOwner);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h
new file mode 100644
index 0000000..6db9322
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSString_h
+#define JSString_h
+
+#include "CommonIdentifiers.h"
+#include "CallFrame.h"
+#include "Identifier.h"
+#include "JSNumberCell.h"
+#include "PropertySlot.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 JIT;
+ friend class VPtrSet;
+
+ public:
+ JSString(JSGlobalData* globalData, const UString& value)
+ : JSCell(globalData->stringStructure.get())
+ , m_value(value)
+ {
+ Heap::heap(this)->reportExtraMemoryCost(value.cost());
+ }
+
+ enum HasOtherOwnerType { HasOtherOwner };
+ JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
+ : JSCell(globalData->stringStructure.get())
+ , m_value(value)
+ {
+ }
+ JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
+ : JSCell(globalData->stringStructure.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 getStringPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned&) const;
+
+ bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
+ JSString* getIndex(JSGlobalData*, unsigned);
+
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
+
+ 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;
+ }
+
+ inline bool isJSString(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsStringVPtr; }
+
+ // --- 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h
new file mode 100644
index 0000000..68f2890
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSType.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 JSType_h
+#define 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h
new file mode 100644
index 0000000..bea188b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h
@@ -0,0 +1,72 @@
+// -*- 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 JSTypeInfo_h
+#define JSTypeInfo_h
+
+#include "JSType.h"
+
+namespace JSC {
+
+ // WebCore uses MasqueradesAsUndefined to make document.all and style.filter undetectable.
+ static const unsigned MasqueradesAsUndefined = 1;
+ static const unsigned ImplementsHasInstance = 1 << 1;
+ static const unsigned OverridesHasInstance = 1 << 2;
+ static const unsigned ImplementsDefaultHasInstance = 1 << 3;
+ static const unsigned NeedsThisConversion = 1 << 4;
+ static const unsigned HasStandardGetOwnPropertySlot = 1 << 5;
+
+ class TypeInfo {
+ friend class JIT;
+ public:
+ TypeInfo(JSType type, unsigned flags = 0)
+ : m_type(type)
+ {
+ // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
+ if ((flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
+ m_flags = flags | ImplementsDefaultHasInstance;
+ else
+ m_flags = flags;
+ }
+
+ JSType type() const { return m_type; }
+
+ bool masqueradesAsUndefined() const { return m_flags & MasqueradesAsUndefined; }
+ bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; }
+ bool overridesHasInstance() const { return m_flags & OverridesHasInstance; }
+ bool needsThisConversion() const { return m_flags & NeedsThisConversion; }
+ bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; }
+
+ unsigned flags() const { return m_flags; }
+
+ private:
+ JSType m_type;
+ unsigned m_flags;
+ };
+
+}
+
+#endif // JSTypeInfo_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp
new file mode 100644
index 0000000..885914d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSValue.h"
+
+#include "JSFunction.h"
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+static const double D32 = 4294967296.0;
+
+// ECMA 9.4
+double JSValue::toInteger(ExecState* exec) const
+{
+ if (isInt32Fast())
+ return getInt32Fast();
+ double d = toNumber(exec);
+ return isnan(d) ? 0.0 : trunc(d);
+}
+
+double JSValue::toIntegerPreserveNaN(ExecState* exec) const
+{
+ if (isInt32Fast())
+ return getInt32Fast();
+ 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);
+}
+
+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);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h
new file mode 100644
index 0000000..391425c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stddef.h> // for size_t
+#include <stdint.h>
+
+#ifndef JSValue_h
+#define JSValue_h
+
+#include "CallData.h"
+#include "ConstructData.h"
+#include <wtf/HashTraits.h>
+#include <wtf/AlwaysInline.h>
+
+namespace JSC {
+
+ class Identifier;
+ class JSCell;
+ class JSGlobalData;
+ class JSImmediate;
+ class JSObject;
+ class JSString;
+ class PropertySlot;
+ class PutPropertySlot;
+ class UString;
+
+ struct ClassInfo;
+ struct Instruction;
+
+ enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
+
+ typedef void* EncodedJSValue;
+
+ class JSValue {
+ friend class JSImmediate;
+ friend struct JSValueHashTraits;
+
+ static JSValue makeImmediate(intptr_t value)
+ {
+ return JSValue(reinterpret_cast<JSCell*>(value));
+ }
+
+ intptr_t immediateValue()
+ {
+ return reinterpret_cast<intptr_t>(m_ptr);
+ }
+
+ public:
+ enum JSNullTag { JSNull };
+ enum JSUndefinedTag { JSUndefined };
+ enum JSTrueTag { JSTrue };
+ enum JSFalseTag { JSFalse };
+
+ static EncodedJSValue encode(JSValue value);
+ static JSValue decode(EncodedJSValue ptr);
+
+ JSValue();
+ JSValue(JSNullTag);
+ JSValue(JSUndefinedTag);
+ JSValue(JSTrueTag);
+ JSValue(JSFalseTag);
+ JSValue(JSCell* ptr);
+ JSValue(const JSCell* ptr);
+
+ // Numbers
+ JSValue(ExecState*, double);
+ JSValue(ExecState*, char);
+ JSValue(ExecState*, unsigned char);
+ JSValue(ExecState*, short);
+ JSValue(ExecState*, unsigned short);
+ JSValue(ExecState*, int);
+ JSValue(ExecState*, unsigned);
+ JSValue(ExecState*, long);
+ JSValue(ExecState*, unsigned long);
+ JSValue(ExecState*, long long);
+ JSValue(ExecState*, unsigned long long);
+ JSValue(JSGlobalData*, double);
+ JSValue(JSGlobalData*, char);
+ JSValue(JSGlobalData*, unsigned char);
+ JSValue(JSGlobalData*, short);
+ JSValue(JSGlobalData*, unsigned short);
+ JSValue(JSGlobalData*, int);
+ JSValue(JSGlobalData*, unsigned);
+ JSValue(JSGlobalData*, long);
+ JSValue(JSGlobalData*, unsigned long);
+ JSValue(JSGlobalData*, long long);
+ JSValue(JSGlobalData*, unsigned long long);
+
+ operator bool() const;
+ bool operator==(const JSValue other) const;
+ bool operator!=(const JSValue other) const;
+
+ // 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
+ bool getNumber(double&) const;
+ 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.
+ // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)'
+ double toInteger(ExecState*) const;
+ double toIntegerPreserveNaN(ExecState*) const;
+ int32_t toInt32(ExecState*) const;
+ int32_t toInt32(ExecState*, bool& ok) const;
+ bool numberToInt32(int32_t& arg);
+ uint32_t toUInt32(ExecState*) const;
+ uint32_t toUInt32(ExecState*, bool& ok) const;
+ bool numberToUInt32(uint32_t& arg);
+
+ // Fast integer operations; these values return results where the value is trivially available
+ // in a convenient form, for use in optimizations. No assumptions should be made based on the
+ // results of these operations, for example !isInt32Fast() does not necessarily indicate the
+ // result of getNumber will not be 0.
+ bool isInt32Fast() const;
+ int32_t getInt32Fast() const;
+ bool isUInt32Fast() const;
+ uint32_t getUInt32Fast() const;
+ static JSValue makeInt32Fast(int32_t);
+ static bool areBothInt32Fast(JSValue, JSValue);
+
+ // Floating point conversions (this is a convenience method for webcore;
+ // signle precision float is not a representation used in JS or JSC).
+ float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
+
+ // API Mangled Numbers
+ bool isAPIMangledNumber();
+
+ // Garbage collection.
+ void mark();
+ bool marked() const;
+
+ // Object operations, with the toObject operation included.
+ JSValue get(ExecState*, const Identifier& propertyName) const;
+ JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
+ 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 needsThisConversion() const;
+ JSObject* toThisObject(ExecState*) const;
+ UString toThisString(ExecState*) const;
+ JSString* toThisJSString(ExecState*);
+
+ static bool equal(ExecState* exec, JSValue v1, JSValue v2);
+ static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
+ static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
+ static bool strictEqual(JSValue v1, JSValue v2);
+ static bool strictEqualSlowCase(JSValue v1, JSValue v2);
+ static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2);
+
+ JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
+
+ bool isCell() const;
+ JSCell* asCell() const;
+
+ private:
+ enum HashTableDeletedValueTag { HashTableDeletedValue };
+ JSValue(HashTableDeletedValueTag);
+
+ inline const JSValue asValue() const { return *this; }
+
+ bool isDoubleNumber() const;
+ double getDoubleNumber() const;
+
+ JSCell* m_ptr;
+ };
+
+ struct JSValueHashTraits : HashTraits<EncodedJSValue> {
+ static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
+ static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
+ };
+
+ // Stand-alone helper functions.
+ inline JSValue jsNull()
+ {
+ return JSValue(JSValue::JSNull);
+ }
+
+ inline JSValue jsUndefined()
+ {
+ return JSValue(JSValue::JSUndefined);
+ }
+
+ inline JSValue jsBoolean(bool b)
+ {
+ return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
+ {
+ return JSValue(exec, d);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
+ {
+ return JSValue(exec, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
+ {
+ return JSValue(globalData, d);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, char i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned char i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, short i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned short i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, long long i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned long long i)
+ {
+ return JSValue(globalData, i);
+ }
+
+ inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
+ inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
+
+ inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
+ inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
+
+ // JSValue member functions.
+ inline EncodedJSValue JSValue::encode(JSValue value)
+ {
+ return reinterpret_cast<EncodedJSValue>(value.m_ptr);
+ }
+
+ inline JSValue JSValue::decode(EncodedJSValue ptr)
+ {
+ return JSValue(reinterpret_cast<JSCell*>(ptr));
+ }
+
+ // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
+ inline JSValue::JSValue()
+ : m_ptr(0)
+ {
+ }
+
+ // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
+ inline JSValue::JSValue(HashTableDeletedValueTag)
+ : m_ptr(reinterpret_cast<JSCell*>(0x4))
+ {
+ }
+
+ inline JSValue::JSValue(JSCell* ptr)
+ : m_ptr(ptr)
+ {
+ }
+
+ inline JSValue::JSValue(const JSCell* ptr)
+ : m_ptr(const_cast<JSCell*>(ptr))
+ {
+ }
+
+ inline JSValue::operator bool() const
+ {
+ return m_ptr;
+ }
+
+ inline bool JSValue::operator==(const JSValue other) const
+ {
+ return m_ptr == other.m_ptr;
+ }
+
+ inline bool JSValue::operator!=(const JSValue other) const
+ {
+ return m_ptr != other.m_ptr;
+ }
+
+ inline bool JSValue::isUndefined() const
+ {
+ return asValue() == jsUndefined();
+ }
+
+ inline bool JSValue::isNull() const
+ {
+ return asValue() == jsNull();
+ }
+
+} // namespace JSC
+
+#endif // JSValue_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp
new file mode 100644
index 0000000..78993b6
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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, bool checkDontDelete)
+{
+ if (symbolTable().contains(propertyName.ustring().rep()))
+ return false;
+
+ return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
+}
+
+void JSVariableObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes)
+{
+ SymbolTable::const_iterator end = symbolTable().end();
+ for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
+ if ((listedAttributes & Structure::NonEnumerable) || !(it->second.getAttributes() & DontEnum))
+ propertyNames.add(Identifier(exec, it->first.get()));
+ }
+
+ JSObject::getPropertyNames(exec, propertyNames, listedAttributes);
+}
+
+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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h
new file mode 100644
index 0000000..310efb1
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h
@@ -0,0 +1,164 @@
+/*
+ * 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 {
+ friend class JIT;
+
+ public:
+ SymbolTable& symbolTable() const { return *d->symbolTable; }
+
+ virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
+
+ virtual bool deleteProperty(ExecState*, const Identifier&, bool checkDontDelete = true);
+ virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype);
+
+ virtual 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.
+
+ private:
+ JSVariableObjectData(const JSVariableObjectData&);
+ JSVariableObjectData& operator=(const JSVariableObjectData&);
+ };
+
+ JSVariableObject(PassRefPtr<Structure> structure, JSVariableObjectData* data)
+ : JSObject(structure)
+ , 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;
+ };
+
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.cpp
new file mode 100644
index 0000000..fb57018
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h
new file mode 100644
index 0000000..2a2e3c6
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006 Maks Orlovich
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 JSWrapperObject_h
+#define 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<Structure>);
+
+ public:
+ JSValue internalValue() const { return m_internalValue; }
+ void setInternalValue(JSValue);
+
+ virtual void mark();
+
+ private:
+ JSValue m_internalValue;
+ };
+
+ inline JSWrapperObject::JSWrapperObject(PassRefPtr<Structure> structure)
+ : JSObject(structure)
+ {
+ }
+
+ inline void JSWrapperObject::setInternalValue(JSValue value)
+ {
+ ASSERT(value);
+ ASSERT(!value.isObject());
+ m_internalValue = value;
+ }
+
+} // namespace JSC
+
+#endif // JSWrapperObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp
new file mode 100644
index 0000000..798013a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LiteralParser.h"
+
+#include "JSArray.h"
+#include "JSString.h"
+#include "Lexer.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/dtoa.h>
+
+namespace JSC {
+
+LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token)
+{
+ while (m_ptr < m_end && isASCIISpace(*m_ptr))
+ ++m_ptr;
+
+ ASSERT(m_ptr <= m_end);
+ if (m_ptr >= m_end) {
+ token.type = TokEnd;
+ token.start = token.end = m_ptr;
+ return TokEnd;
+ }
+ token.type = TokError;
+ token.start = m_ptr;
+ switch (*m_ptr) {
+ case '[':
+ token.type = TokLBracket;
+ token.end = ++m_ptr;
+ return TokLBracket;
+ case ']':
+ token.type = TokRBracket;
+ token.end = ++m_ptr;
+ return TokRBracket;
+ case '(':
+ token.type = TokLParen;
+ token.end = ++m_ptr;
+ return TokLBracket;
+ case ')':
+ token.type = TokRParen;
+ token.end = ++m_ptr;
+ return TokRBracket;
+ case '{':
+ token.type = TokLBrace;
+ token.end = ++m_ptr;
+ return TokLBrace;
+ case '}':
+ token.type = TokRBrace;
+ token.end = ++m_ptr;
+ return TokRBrace;
+ case ',':
+ token.type = TokComma;
+ token.end = ++m_ptr;
+ return TokComma;
+ case ':':
+ token.type = TokColon;
+ token.end = ++m_ptr;
+ return TokColon;
+ case '"':
+ if (m_mode == StrictJSON)
+ return lexString<StrictJSON>(token);
+ return lexString<NonStrictJSON>(token);
+ case 't':
+ if (m_end - m_ptr >= 4 && m_ptr[1] == 'r' && m_ptr[2] == 'u' && m_ptr[3] == 'e') {
+ m_ptr += 4;
+ token.type = TokTrue;
+ token.end = m_ptr;
+ return TokTrue;
+ }
+ break;
+ case 'f':
+ if (m_end - m_ptr >= 5 && m_ptr[1] == 'a' && m_ptr[2] == 'l' && m_ptr[3] == 's' && m_ptr[4] == 'e') {
+ m_ptr += 5;
+ token.type = TokFalse;
+ token.end = m_ptr;
+ return TokFalse;
+ }
+ break;
+ case 'n':
+ if (m_end - m_ptr >= 4 && m_ptr[1] == 'u' && m_ptr[2] == 'l' && m_ptr[3] == 'l') {
+ m_ptr += 4;
+ token.type = TokNull;
+ token.end = m_ptr;
+ return TokNull;
+ }
+ break;
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return lexNumber(token);
+ }
+ return TokError;
+}
+
+template <LiteralParser::ParserMode mode> static inline bool isSafeStringCharacter(UChar c)
+{
+ return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != '"') || c == '\t';
+}
+
+template <LiteralParser::ParserMode mode> LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token)
+{
+ ++m_ptr;
+ const UChar* runStart;
+ token.stringToken = UString();
+ do {
+ runStart = m_ptr;
+ while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr))
+ ++m_ptr;
+ if (runStart < m_ptr)
+ token.stringToken.append(runStart, m_ptr - runStart);
+ if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') {
+ ++m_ptr;
+ if (m_ptr >= m_end)
+ return TokError;
+ switch (*m_ptr) {
+ case '"':
+ token.stringToken.append('"');
+ m_ptr++;
+ break;
+ case '\\':
+ token.stringToken.append('\\');
+ m_ptr++;
+ break;
+ case '/':
+ token.stringToken.append('/');
+ m_ptr++;
+ break;
+ case 'b':
+ token.stringToken.append('\b');
+ m_ptr++;
+ break;
+ case 'f':
+ token.stringToken.append('\f');
+ m_ptr++;
+ break;
+ case 'n':
+ token.stringToken.append('\n');
+ m_ptr++;
+ break;
+ case 'r':
+ token.stringToken.append('\r');
+ m_ptr++;
+ break;
+ case 't':
+ token.stringToken.append('\t');
+ m_ptr++;
+ break;
+
+ case 'u':
+ if ((m_end - m_ptr) < 5) // uNNNN == 5 characters
+ return TokError;
+ for (int i = 1; i < 5; i++) {
+ if (!isASCIIHexDigit(m_ptr[i]))
+ return TokError;
+ }
+ token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
+ m_ptr += 5;
+ break;
+
+ default:
+ return TokError;
+ }
+ }
+ } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"');
+
+ if (m_ptr >= m_end || *m_ptr != '"')
+ return TokError;
+
+ token.type = TokString;
+ token.end = ++m_ptr;
+ return TokString;
+}
+
+LiteralParser::TokenType LiteralParser::Lexer::lexNumber(LiteralParserToken& token)
+{
+ // ES5 and json.org define numbers as
+ // number
+ // int
+ // int frac? exp?
+ //
+ // int
+ // -? 0
+ // -? digit1-9 digits?
+ //
+ // digits
+ // digit digits?
+ //
+ // -?(0 | [1-9][0-9]*) ('.' [0-9]+)? ([eE][+-]? [0-9]+)?
+
+ if (m_ptr < m_end && *m_ptr == '-') // -?
+ ++m_ptr;
+
+ // (0 | [1-9][0-9]*)
+ if (m_ptr < m_end && *m_ptr == '0') // 0
+ ++m_ptr;
+ else if (m_ptr < m_end && *m_ptr >= '1' && *m_ptr <= '9') { // [1-9]
+ ++m_ptr;
+ // [0-9]*
+ while (m_ptr < m_end && isASCIIDigit(*m_ptr))
+ ++m_ptr;
+ } else
+ return TokError;
+
+ // ('.' [0-9]+)?
+ if (m_ptr < m_end && *m_ptr == '.') {
+ ++m_ptr;
+ // [0-9]+
+ if (m_ptr >= m_end || !isASCIIDigit(*m_ptr))
+ return TokError;
+
+ ++m_ptr;
+ while (m_ptr < m_end && isASCIIDigit(*m_ptr))
+ ++m_ptr;
+ }
+
+ // ([eE][+-]? [0-9]+)?
+ if (m_ptr < m_end && (*m_ptr == 'e' || *m_ptr == 'E')) { // [eE]
+ ++m_ptr;
+
+ // [-+]?
+ if (m_ptr < m_end && (*m_ptr == '-' || *m_ptr == '+'))
+ ++m_ptr;
+
+ // [0-9]+
+ if (m_ptr >= m_end || !isASCIIDigit(*m_ptr))
+ return TokError;
+
+ ++m_ptr;
+ while (m_ptr < m_end && isASCIIDigit(*m_ptr))
+ ++m_ptr;
+ }
+
+ token.type = TokNumber;
+ token.end = m_ptr;
+ Vector<char, 64> buffer(token.end - token.start + 1);
+ int i;
+ for (i = 0; i < token.end - token.start; i++) {
+ ASSERT(static_cast<char>(token.start[i]) == token.start[i]);
+ buffer[i] = static_cast<char>(token.start[i]);
+ }
+ buffer[i] = 0;
+ char* end;
+ token.numberToken = WTF::strtod(buffer.data(), &end);
+ ASSERT(buffer.data() + (token.end - token.start) == end);
+ return TokNumber;
+}
+
+JSValue LiteralParser::parse(ParserState initialState)
+{
+ ParserState state = initialState;
+ MarkedArgumentBuffer objectStack;
+ JSValue lastValue;
+ Vector<ParserState, 16> stateStack;
+ Vector<Identifier, 16> identifierStack;
+ while (1) {
+ switch(state) {
+ startParseArray:
+ case StartParseArray: {
+ JSArray* array = constructEmptyArray(m_exec);
+ objectStack.append(array);
+ // fallthrough
+ }
+ doParseArrayStartExpression:
+ case DoParseArrayStartExpression: {
+ if (m_lexer.next() == TokRBracket) {
+ m_lexer.next();
+ lastValue = objectStack.last();
+ objectStack.removeLast();
+ break;
+ }
+
+ stateStack.append(DoParseArrayEndExpression);
+ goto startParseExpression;
+ }
+ case DoParseArrayEndExpression: {
+ asArray(objectStack.last())->push(m_exec, lastValue);
+
+ if (m_lexer.currentToken().type == TokComma)
+ goto doParseArrayStartExpression;
+
+ if (m_lexer.currentToken().type != TokRBracket)
+ return JSValue();
+
+ m_lexer.next();
+ lastValue = objectStack.last();
+ objectStack.removeLast();
+ break;
+ }
+ startParseObject:
+ case StartParseObject: {
+ JSObject* object = constructEmptyObject(m_exec);
+ objectStack.append(object);
+
+ TokenType type = m_lexer.next();
+ if (type == TokString) {
+ Lexer::LiteralParserToken identifierToken = m_lexer.currentToken();
+
+ // Check for colon
+ if (m_lexer.next() != TokColon)
+ return JSValue();
+
+ m_lexer.next();
+ identifierStack.append(Identifier(m_exec, identifierToken.stringToken));
+ stateStack.append(DoParseObjectEndExpression);
+ goto startParseExpression;
+ } else if (type != TokRBrace)
+ return JSValue();
+ m_lexer.next();
+ lastValue = objectStack.last();
+ objectStack.removeLast();
+ break;
+ }
+ doParseObjectStartExpression:
+ case DoParseObjectStartExpression: {
+ TokenType type = m_lexer.next();
+ if (type != TokString)
+ return JSValue();
+ Lexer::LiteralParserToken identifierToken = m_lexer.currentToken();
+
+ // Check for colon
+ if (m_lexer.next() != TokColon)
+ return JSValue();
+
+ m_lexer.next();
+ identifierStack.append(Identifier(m_exec, identifierToken.stringToken));
+ stateStack.append(DoParseObjectEndExpression);
+ goto startParseExpression;
+ }
+ case DoParseObjectEndExpression:
+ {
+ asObject(objectStack.last())->putDirect(identifierStack.last(), lastValue);
+ identifierStack.removeLast();
+ if (m_lexer.currentToken().type == TokComma)
+ goto doParseObjectStartExpression;
+ if (m_lexer.currentToken().type != TokRBrace)
+ return JSValue();
+ m_lexer.next();
+ lastValue = objectStack.last();
+ objectStack.removeLast();
+ break;
+ }
+ startParseExpression:
+ case StartParseExpression: {
+ switch (m_lexer.currentToken().type) {
+ case TokLBracket:
+ goto startParseArray;
+ case TokLBrace:
+ goto startParseObject;
+ case TokString: {
+ Lexer::LiteralParserToken stringToken = m_lexer.currentToken();
+ m_lexer.next();
+ lastValue = jsString(m_exec, stringToken.stringToken);
+ break;
+ }
+ case TokNumber: {
+ Lexer::LiteralParserToken numberToken = m_lexer.currentToken();
+ m_lexer.next();
+ lastValue = jsNumber(m_exec, numberToken.numberToken);
+ break;
+ }
+ case TokNull:
+ m_lexer.next();
+ lastValue = jsNull();
+ break;
+
+ case TokTrue:
+ m_lexer.next();
+ lastValue = jsBoolean(true);
+ break;
+
+ case TokFalse:
+ m_lexer.next();
+ lastValue = jsBoolean(false);
+ break;
+
+ default:
+ // Error
+ return JSValue();
+ }
+ break;
+ }
+ case StartParseStatement: {
+ switch (m_lexer.currentToken().type) {
+ case TokLBracket:
+ case TokNumber:
+ case TokString:
+ goto startParseExpression;
+
+ case TokLParen: {
+ m_lexer.next();
+ stateStack.append(StartParseStatementEndStatement);
+ goto startParseExpression;
+ }
+ default:
+ return JSValue();
+ }
+ }
+ case StartParseStatementEndStatement: {
+ ASSERT(stateStack.isEmpty());
+ if (m_lexer.currentToken().type != TokRParen)
+ return JSValue();
+ if (m_lexer.next() == TokEnd)
+ return lastValue;
+ return JSValue();
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ if (stateStack.isEmpty())
+ return lastValue;
+ state = stateStack.last();
+ stateStack.removeLast();
+ continue;
+ }
+}
+
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h
new file mode 100644
index 0000000..bceee7c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LiteralParser_h
+#define LiteralParser_h
+
+#include "JSGlobalObjectFunctions.h"
+#include "JSValue.h"
+#include "UString.h"
+
+namespace JSC {
+
+ class LiteralParser {
+ public:
+ typedef enum { StrictJSON, NonStrictJSON } ParserMode;
+ LiteralParser(ExecState* exec, const UString& s, ParserMode mode)
+ : m_exec(exec)
+ , m_lexer(s, mode)
+ , m_mode(mode)
+ {
+ }
+
+ JSValue tryLiteralParse()
+ {
+ m_lexer.next();
+ JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
+ if (m_lexer.currentToken().type != TokEnd)
+ return JSValue();
+ return result;
+ }
+ private:
+ enum ParserState { StartParseObject, StartParseArray, StartParseExpression,
+ StartParseStatement, StartParseStatementEndStatement,
+ DoParseObjectStartExpression, DoParseObjectEndExpression,
+ DoParseArrayStartExpression, DoParseArrayEndExpression };
+ enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
+ TokString, TokIdentifier, TokNumber, TokColon,
+ TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
+ TokNull, TokEnd, TokError };
+
+ class Lexer {
+ public:
+ struct LiteralParserToken {
+ TokenType type;
+ const UChar* start;
+ const UChar* end;
+ UString stringToken;
+ double numberToken;
+ };
+ Lexer(const UString& s, ParserMode mode)
+ : m_string(s)
+ , m_mode(mode)
+ , m_ptr(s.data())
+ , m_end(s.data() + s.size())
+ {
+ }
+
+ TokenType next()
+ {
+ return lex(m_currentToken);
+ }
+
+ const LiteralParserToken& currentToken()
+ {
+ return m_currentToken;
+ }
+
+ private:
+ TokenType lex(LiteralParserToken&);
+ template <ParserMode parserMode> TokenType lexString(LiteralParserToken&);
+ TokenType lexNumber(LiteralParserToken&);
+ LiteralParserToken m_currentToken;
+ UString m_string;
+ ParserMode m_mode;
+ const UChar* m_ptr;
+ const UChar* m_end;
+ };
+
+ class StackGuard;
+ JSValue parse(ParserState);
+
+ ExecState* m_exec;
+ LiteralParser::Lexer m_lexer;
+ ParserMode m_mode;
+ };
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp
new file mode 100644
index 0000000..8359ff7
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 "Lookup.h"
+
+#include "JSFunction.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+void HashTable::createTable(JSGlobalData* globalData) const
+{
+ ASSERT(!table);
+ int linkIndex = compactHashSizeMask + 1;
+ HashEntry* entries = new HashEntry[compactSize];
+ for (int i = 0; i < compactSize; ++i)
+ entries[i].setKey(0);
+ for (int i = 0; values[i].key; ++i) {
+ UString::Rep* identifier = Identifier::add(globalData, values[i].key).releaseRef();
+ int hashIndex = identifier->computedHash() & compactHashSizeMask;
+ HashEntry* entry = &entries[hashIndex];
+
+ if (entry->key()) {
+ while (entry->next()) {
+ entry = entry->next();
+ }
+ ASSERT(linkIndex < compactSize);
+ entry->setNext(&entries[linkIndex++]);
+ entry = entry->next();
+ }
+
+ entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
+ }
+ table = entries;
+}
+
+void HashTable::deleteTable() const
+{
+ if (table) {
+ int max = compactSize;
+ for (int i = 0; i != max; ++i) {
+ if (UString::Rep* key = table[i].key())
+ key->deref();
+ }
+ delete [] table;
+ table = 0;
+ }
+}
+
+void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
+{
+ ASSERT(entry->attributes() & Function);
+ JSValue* location = thisObj->getDirectLocation(propertyName);
+
+ if (!location) {
+ InternalFunction* function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
+
+ thisObj->putDirectFunction(propertyName, function, entry->attributes());
+ location = thisObj->getDirectLocation(propertyName);
+ }
+
+ slot.setValueSlot(thisObj, location, thisObj->offsetForLocation(location));
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h
new file mode 100644
index 0000000..167f2bc
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * 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 Lookup_h
+#define Lookup_h
+
+#include "CallFrame.h"
+#include "Identifier.h"
+#include "JSGlobalObject.h"
+#include "JSObject.h"
+#include "PropertySlot.h"
+#include <stdio.h>
+#include <wtf/Assertions.h>
+
+// Bug #26843: Work around Metrowerks compiler bug
+#if COMPILER(WINSCW)
+#define JSC_CONST_HASHTABLE
+#else
+#define JSC_CONST_HASHTABLE const
+#endif
+
+namespace JSC {
+
+ // Hash table generated by the create_hash_table script.
+ struct HashTableValue {
+ const char* key; // property name
+ unsigned char attributes; // JSObject attributes
+ intptr_t value1;
+ intptr_t value2;
+ };
+
+ // FIXME: There is no reason this get function can't be simpler.
+ // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
+ typedef PropertySlot::GetValueFunc GetFunction;
+ typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue value);
+
+ class HashEntry {
+ public:
+ void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2)
+ {
+ m_key = key;
+ m_attributes = attributes;
+ m_u.store.value1 = v1;
+ m_u.store.value2 = v2;
+ m_next = 0;
+ }
+
+ void setKey(UString::Rep* key) { m_key = key; }
+ UString::Rep* key() const { return m_key; }
+
+ unsigned char attributes() const { return m_attributes; }
+
+ NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
+ unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }
+
+ GetFunction propertyGetter() const { ASSERT(!(m_attributes & Function)); return m_u.property.get; }
+ PutFunction propertyPutter() const { ASSERT(!(m_attributes & Function)); return m_u.property.put; }
+
+ intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
+
+ void setNext(HashEntry *next) { m_next = next; }
+ HashEntry* next() const { return m_next; }
+
+ private:
+ UString::Rep* m_key;
+ unsigned char m_attributes; // JSObject attributes
+
+ union {
+ struct {
+ intptr_t value1;
+ intptr_t value2;
+ } store;
+ struct {
+ NativeFunction functionValue;
+ intptr_t length; // number of arguments for function
+ } function;
+ struct {
+ GetFunction get;
+ PutFunction put;
+ } property;
+ struct {
+ intptr_t value;
+ intptr_t unused;
+ } lexer;
+ } m_u;
+
+ HashEntry* m_next;
+ };
+
+ struct HashTable {
+
+ int compactSize;
+ int compactHashSizeMask;
+
+ const HashTableValue* values; // Fixed values generated by script.
+ mutable const HashEntry* table; // Table allocated at runtime.
+
+ ALWAYS_INLINE void initializeIfNeeded(JSGlobalData* globalData) const
+ {
+ if (!table)
+ createTable(globalData);
+ }
+
+ ALWAYS_INLINE void initializeIfNeeded(ExecState* exec) const
+ {
+ if (!table)
+ createTable(&exec->globalData());
+ }
+
+ void deleteTable() const;
+
+ // Find an entry in the table, and return the entry.
+ ALWAYS_INLINE const HashEntry* entry(JSGlobalData* globalData, const Identifier& identifier) const
+ {
+ initializeIfNeeded(globalData);
+ return entry(identifier);
+ }
+
+ ALWAYS_INLINE const HashEntry* entry(ExecState* exec, const Identifier& identifier) const
+ {
+ initializeIfNeeded(exec);
+ return entry(identifier);
+ }
+
+ private:
+ ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
+ {
+ ASSERT(table);
+
+ const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];
+
+ if (!entry->key())
+ return 0;
+
+ do {
+ if (entry->key() == identifier.ustring().rep())
+ return entry;
+ entry = entry->next();
+ } while (entry);
+
+ return 0;
+ }
+
+ // Convert the hash table keys to identifiers.
+ void createTable(JSGlobalData*) const;
+ };
+
+ void setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, const Identifier& propertyName, PropertySlot&);
+
+ /**
+ * This method does it all (looking in the hashtable, checking for function
+ * overrides, creating the function or retrieving from cache, calling
+ * getValueProperty in case of a non-function property, forwarding to parent if
+ * unknown property).
+ */
+ template <class ThisImp, class ParentImp>
+ inline bool getStaticPropertySlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
+ {
+ const HashEntry* entry = table->entry(exec, propertyName);
+
+ if (!entry) // not found, forward to parent
+ return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
+
+ if (entry->attributes() & Function)
+ setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
+ else
+ slot.setCustom(thisObj, entry->propertyGetter());
+
+ return true;
+ }
+
+ /**
+ * Simplified version of getStaticPropertySlot in case there are only functions.
+ * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
+ * a dummy getValueProperty.
+ */
+ template <class ParentImp>
+ inline bool getStaticFunctionSlot(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
+ {
+ if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertySlot(exec, propertyName, slot))
+ return true;
+
+ const HashEntry* entry = table->entry(exec, propertyName);
+ if (!entry)
+ return false;
+
+ setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
+ return true;
+ }
+
+ /**
+ * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
+ * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
+ */
+ template <class ThisImp, class ParentImp>
+ inline bool getStaticValueSlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot)
+ {
+ const HashEntry* entry = table->entry(exec, propertyName);
+
+ if (!entry) // not found, forward to parent
+ return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot);
+
+ ASSERT(!(entry->attributes() & Function));
+
+ slot.setCustom(thisObj, entry->propertyGetter());
+ return true;
+ }
+
+ /**
+ * This one is for "put".
+ * It looks up a hash entry for the property to be set. If an entry
+ * is found it sets the value and returns true, else it returns false.
+ */
+ template <class ThisImp>
+ inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj)
+ {
+ const HashEntry* entry = table->entry(exec, propertyName);
+
+ if (!entry)
+ return false;
+
+ if (entry->attributes() & Function) { // function: put as override property
+ if (LIKELY(value.isCell()))
+ thisObj->putDirectFunction(propertyName, value.asCell());
+ else
+ thisObj->putDirect(propertyName, value);
+ } else if (!(entry->attributes() & ReadOnly))
+ entry->propertyPutter()(exec, thisObj, value);
+
+ return true;
+ }
+
+ /**
+ * This one is for "put".
+ * It calls lookupPut<ThisImp>() to set the value. If that call
+ * returns false (meaning no entry in the hash table was found),
+ * then it calls put() on the ParentImp class.
+ */
+ template <class ThisImp, class ParentImp>
+ inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
+ {
+ if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
+ thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent
+ }
+
+} // namespace JSC
+
+#endif // Lookup_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp
new file mode 100644
index 0000000..2572bc9
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "MathObject.h"
+
+#include "ObjectPrototype.h"
+#include "Operations.h"
+#include <time.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/RandomNumber.h>
+#include <wtf/RandomNumberSeed.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(MathObject);
+
+static JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncMin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL 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<Structure> 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);
+ WTF::initializeWeakRandomNumberGenerator();
+}
+
+// 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 JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, fabs(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, acos(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, asin(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, atan(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, ceil(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, cos(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, exp(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, floor(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, log(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL 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(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 JSC_HOST_CALL 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(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 JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ // ECMA 15.8.2.1.13
+
+ double arg = args.at(0).toNumber(exec);
+ double arg2 = args.at(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 JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
+{
+ return jsNumber(exec, WTF::weakRandomNumber());
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ double arg = args.at(0).toNumber(exec);
+ if (signbit(arg) && arg >= -0.5)
+ return jsNumber(exec, -0.0);
+ return jsNumber(exec, floor(arg + 0.5));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, sin(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, sqrt(args.at(0).toNumber(exec)));
+}
+
+JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, tan(args.at(0).toNumber(exec)));
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h
new file mode 100644
index 0000000..3557d1e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef MathObject_h
+#define MathObject_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ class MathObject : public JSObject {
+ public:
+ MathObject(ExecState*, PassRefPtr<Structure>);
+
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+ };
+
+} // namespace JSC
+
+#endif // MathObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp
new file mode 100644
index 0000000..0205fc5
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "NativeErrorConstructor.h"
+
+#include "ErrorInstance.h"
+#include "JSFunction.h"
+#include "JSString.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<Structure> structure, NativeErrorPrototype* nativeErrorPrototype)
+ : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name).getString()))
+ , m_errorStructure(ErrorInstance::createStructure(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(0).isUndefined())
+ object->putDirect(exec->propertyNames().message, jsString(exec, args.at(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 JSC_HOST_CALL 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h
new file mode 100644
index 0000000..118d1f4
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef NativeErrorConstructor_h
+#define NativeErrorConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class ErrorInstance;
+ class FunctionPrototype;
+ class NativeErrorPrototype;
+
+ class NativeErrorConstructor : public InternalFunction {
+ public:
+ NativeErrorConstructor(ExecState*, PassRefPtr<Structure>, 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<Structure> m_errorStructure;
+ };
+
+} // namespace JSC
+
+#endif // NativeErrorConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp
new file mode 100644
index 0000000..650a0fd
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "NativeErrorPrototype.h"
+
+#include "ErrorPrototype.h"
+#include "JSString.h"
+#include "UString.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
+
+NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, const UString& name, const UString& message)
+#ifdef QT_BUILD_SCRIPT_LIB
+ : ErrorInstance(structure)
+#else
+ : JSObject(structure)
+#endif
+{
+ putDirect(exec->propertyNames().name, jsString(exec, name), 0);
+ putDirect(exec->propertyNames().message, jsString(exec, message), 0);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h
new file mode 100644
index 0000000..48a9d7e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef NativeErrorPrototype_h
+#define NativeErrorPrototype_h
+
+#include "JSObject.h"
+#ifdef QT_BUILD_SCRIPT_LIB
+#include "ErrorInstance.h"
+#endif
+
+namespace JSC {
+
+ class NativeErrorPrototype :
+#ifdef QT_BUILD_SCRIPT_LIB //According to ECMAScript Specification 15.11.7, errors must have the "Error" class
+ public ErrorInstance
+#else
+ public JSObject
+#endif
+ {
+ public:
+ NativeErrorPrototype(ExecState*, PassRefPtr<Structure>, const UString& name, const UString& message);
+ };
+
+} // namespace JSC
+
+#endif // NativeErrorPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeFunctionWrapper.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeFunctionWrapper.h
new file mode 100644
index 0000000..d4eeb3b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeFunctionWrapper.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NativeFunctionWrapper_h
+#define NativeFunctionWrapper_h
+
+namespace JSC {
+#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+ class JSFunction;
+ typedef JSFunction NativeFunctionWrapper;
+#else
+ class PrototypeFunction;
+ typedef PrototypeFunction NativeFunctionWrapper;
+#endif
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp
new file mode 100644
index 0000000..2840bf0
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+#include "config.h"
+#include "NumberConstructor.h"
+
+#include "NumberObject.h"
+#include "NumberPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
+
+static JSValue numberConstructorNaNValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorNegInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorPosInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorMaxValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorMinValue(ExecState*, const Identifier&, const PropertySlot&);
+
+} // namespace JSC
+
+#include "NumberConstructor.lut.h"
+
+namespace JSC {
+
+const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable };
+
+/* Source for NumberConstructor.lut.h
+@begin numberTable
+ NaN numberConstructorNaNValue DontEnum|DontDelete|ReadOnly
+ NEGATIVE_INFINITY numberConstructorNegInfinity DontEnum|DontDelete|ReadOnly
+ POSITIVE_INFINITY numberConstructorPosInfinity DontEnum|DontDelete|ReadOnly
+ MAX_VALUE numberConstructorMaxValue DontEnum|DontDelete|ReadOnly
+ MIN_VALUE numberConstructorMinValue DontEnum|DontDelete|ReadOnly
+@end
+*/
+
+NumberConstructor::NumberConstructor(ExecState* exec, PassRefPtr<Structure> 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);
+}
+
+static JSValue numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+ return jsNaN(exec);
+}
+
+static JSValue numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+ return jsNumber(exec, -Inf);
+}
+
+static JSValue numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+ return jsNumber(exec, Inf);
+}
+
+static JSValue numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+ return jsNumber(exec, 1.7976931348623157E+308);
+}
+
+static JSValue numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+{
+ return jsNumber(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(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 JSC_HOST_CALL callNumberConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ return jsNumber(exec, args.isEmpty() ? 0 : args.at(0).toNumber(exec));
+}
+
+CallType NumberConstructor::getCallData(CallData& callData)
+{
+ callData.native.function = callNumberConstructor;
+ return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h
new file mode 100644
index 0000000..b1224ec
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef NumberConstructor_h
+#define NumberConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class NumberPrototype;
+
+ class NumberConstructor : public InternalFunction {
+ public:
+ NumberConstructor(ExecState*, PassRefPtr<Structure>, NumberPrototype*);
+
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+ JSValue getValueProperty(ExecState*, int token) const;
+
+ static const ClassInfo info;
+
+ static PassRefPtr<Structure> createStructure(JSValue proto)
+ {
+ return Structure::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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp
new file mode 100644
index 0000000..0e8df17
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+#include "config.h"
+#include "NumberObject.h"
+
+#include "JSGlobalObject.h"
+#include "NumberPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(NumberObject);
+
+const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
+
+NumberObject::NumberObject(PassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
+{
+}
+
+JSValue NumberObject::getJSNumber()
+{
+ return internalValue();
+}
+
+NumberObject* constructNumber(ExecState* exec, JSValue number)
+{
+ NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
+ object->setInternalValue(number);
+ return object;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h
new file mode 100644
index 0000000..d354b9b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef NumberObject_h
+#define NumberObject_h
+
+#include "JSWrapperObject.h"
+
+namespace JSC {
+
+ class NumberObject : public JSWrapperObject {
+ public:
+ explicit NumberObject(PassRefPtr<Structure>);
+
+ static const ClassInfo info;
+
+ private:
+ virtual const ClassInfo* classInfo() const { return &info; }
+
+ virtual JSValue getJSNumber();
+ };
+
+ NumberObject* constructNumber(ExecState*, JSValue);
+
+} // namespace JSC
+
+#endif // NumberObject_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp
new file mode 100644
index 0000000..947324c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ */
+
+#include "config.h"
+#include "NumberPrototype.h"
+
+#include "Error.h"
+#include "JSFunction.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 JSC_HOST_CALL numberProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue, const ArgList&);
+
+// ECMA 15.7.4
+
+NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+ : NumberObject(structure)
+{
+ setInternalValue(jsNumber(exec, 0));
+
+ // The constructor will be added later, after NumberConstructor has been constructed
+
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(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[80];
+ WTF::dtoa(result, 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) {
+ ASSERT(decimalPoint < 1024);
+ memcpy(buf.data(), result, length);
+ memset(buf.data() + length, '0', decimalPoint - length);
+ } else
+ strncpy(buf.data(), result, decimalPoint);
+ buf[decimalPoint] = '\0';
+
+ str.append(buf.data());
+ }
+
+ 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 JSC_HOST_CALL numberProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSValue v = thisValue.getJSNumber();
+ if (!v)
+ return throwError(exec, TypeError);
+
+ double radixAsDouble = args.at(0).toInteger(exec); // nan -> 0
+ if (radixAsDouble == 10 || args.at(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 JSC_HOST_CALL 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 JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ JSValue v = thisValue.getJSNumber();
+ if (!v)
+ return throwError(exec, TypeError);
+
+ return v;
+}
+
+JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSValue v = thisValue.getJSNumber();
+ if (!v)
+ return throwError(exec, TypeError);
+
+ JSValue fractionDigits = args.at(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 {
+ ASSERT(i + resultLength - 1 < 80);
+ memcpy(buf + i, result + 1, resultLength - 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 JSC_HOST_CALL 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(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[80];
+ WTF::dtoa(result, 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++] = '-';
+
+ // ? 9999 is the magical "result is Inf or NaN" value. what's 999??
+ if (decimalPoint == 999) {
+ ASSERT(i + resultLength < 80);
+ memcpy(buf + i, result, resultLength);
+ buf[i + resultLength] = '\0';
+ } 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);
+
+ return jsString(exec, buf);
+}
+
+JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSValue v = thisValue.getJSNumber();
+ if (!v)
+ return throwError(exec, TypeError);
+
+ double doublePrecision = args.at(0).toIntegerPreserveNaN(exec);
+ double x = v.uncheckedGetNumber();
+ if (args.at(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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h
new file mode 100644
index 0000000..0a3a544
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef NumberPrototype_h
+#define NumberPrototype_h
+
+#include "NumberObject.h"
+
+namespace JSC {
+
+ class NumberPrototype : public NumberObject {
+ public:
+ NumberPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ };
+
+} // namespace JSC
+
+#endif // NumberPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp
new file mode 100644
index 0000000..cf1790f
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "ObjectConstructor.h"
+
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "ObjectPrototype.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
+
+ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype)
+ : InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object"))
+{
+ // 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(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 JSC_HOST_CALL 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h
new file mode 100644
index 0000000..f8c058a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ObjectConstructor_h
+#define ObjectConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class ObjectPrototype;
+
+ class ObjectConstructor : public InternalFunction {
+ public:
+ ObjectConstructor(ExecState*, PassRefPtr<Structure>, ObjectPrototype*);
+
+ private:
+ virtual ConstructType getConstructData(ConstructData&);
+ virtual CallType getCallData(CallData&);
+ };
+
+} // namespace JSC
+
+#endif // ObjectConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp
new file mode 100644
index 0000000..98e4713
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "ObjectPrototype.h"
+
+#include "Error.h"
+#include "JSFunction.h"
+#include "JSString.h"
+#include "PrototypeFunction.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
+
+static JSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+
+ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure)
+ : JSObject(stucture)
+{
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
+
+ // Mozilla extensions
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(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 JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return thisValue.toThisObject(exec);
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ return jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(0).toString(exec))));
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSObject* thisObj = thisValue.toThisObject(exec);
+
+ if (!args.at(0).isObject())
+ return jsBoolean(false);
+
+ JSValue v = asObject(args.at(0))->prototype();
+
+ while (true) {
+ if (!v.isObject())
+ return jsBoolean(false);
+ if (v == thisObj)
+ return jsBoolean(true);
+ v = asObject(v)->prototype();
+ }
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ CallData callData;
+ if (args.at(1).getCallData(callData) == CallTypeNone)
+ return throwError(exec, SyntaxError, "invalid getter usage");
+ thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(0).toString(exec)), asObject(args.at(1)));
+ return jsUndefined();
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ CallData callData;
+ if (args.at(1).getCallData(callData) == CallTypeNone)
+ return throwError(exec, SyntaxError, "invalid setter usage");
+ thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(0).toString(exec)), asObject(args.at(1)));
+ return jsUndefined();
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ return thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(0).toString(exec)));
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ return thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(0).toString(exec)));
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ return jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(0).toString(exec))));
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return thisValue.toThisJSString(exec);
+}
+
+JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h
new file mode 100644
index 0000000..7790ae0
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef ObjectPrototype_h
+#define ObjectPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ class ObjectPrototype : public JSObject {
+ public:
+ ObjectPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ };
+
+ JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+
+} // namespace JSC
+
+#endif // ObjectPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp
new file mode 100644
index 0000000..093bbec
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 "Operations.h"
+
+#include "Error.h"
+#include "JSObject.h"
+#include "JSString.h"
+#include <math.h>
+#include <stdio.h>
+#include <wtf/MathExtras.h>
+
+#if HAVE(FLOAT_H)
+#include <float.h>
+#endif
+
+namespace JSC {
+
+bool JSValue::equalSlowCase(ExecState* exec, JSValue v1, JSValue v2)
+{
+ return equalSlowCaseInline(exec, v1, v2);
+}
+
+bool JSValue::strictEqualSlowCase(JSValue v1, JSValue v2)
+{
+ return strictEqualSlowCaseInline(v1, v2);
+}
+
+NEVER_INLINE JSValue throwOutOfMemoryError(ExecState* exec)
+{
+ JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+ exec->setException(error);
+ return error;
+}
+
+NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
+{
+ // exception for the Date exception in defaultValue()
+ JSValue p1 = v1.toPrimitive(callFrame);
+ JSValue p2 = v2.toPrimitive(callFrame);
+
+ if (p1.isString() || p2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
+ }
+
+ return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
+}
+
+JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
+{
+ if (v.isUndefined())
+ return jsNontrivialString(callFrame, "undefined");
+ if (v.isBoolean())
+ return jsNontrivialString(callFrame, "boolean");
+ if (v.isNumber())
+ return jsNontrivialString(callFrame, "number");
+ if (v.isString())
+ return jsNontrivialString(callFrame, "string");
+ if (v.isObject()) {
+ // Return "undefined" for objects that should be treated
+ // as null when doing comparisons.
+ if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+ return jsNontrivialString(callFrame, "undefined");
+ CallData callData;
+ if (asObject(v)->getCallData(callData) != CallTypeNone)
+ return jsNontrivialString(callFrame, "function");
+ }
+ return jsNontrivialString(callFrame, "object");
+}
+
+bool jsIsObjectType(JSValue v)
+{
+ if (!v.isCell())
+ return v.isNull();
+
+ JSType type = asCell(v)->structure()->typeInfo().type();
+ if (type == NumberType || type == StringType)
+ return false;
+ if (type == ObjectType) {
+ if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+ return false;
+ CallData callData;
+ if (asObject(v)->getCallData(callData) != CallTypeNone)
+ return false;
+ }
+ return true;
+}
+
+bool jsIsFunctionType(JSValue v)
+{
+ if (v.isObject()) {
+ CallData callData;
+ if (asObject(v)->getCallData(callData) != CallTypeNone)
+ return true;
+ }
+ return false;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h
new file mode 100644
index 0000000..acfc6c2
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 Operations_h
+#define Operations_h
+
+#include "Interpreter.h"
+#include "JSImmediate.h"
+#include "JSNumberCell.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ NEVER_INLINE JSValue throwOutOfMemoryError(ExecState*);
+ NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
+ JSValue jsTypeStringForValue(CallFrame*, JSValue);
+ bool jsIsObjectType(JSValue);
+ bool jsIsFunctionType(JSValue);
+
+ // ECMA 11.9.3
+ inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
+ {
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+
+ return equalSlowCase(exec, v1, v2);
+ }
+
+ ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
+ {
+ ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2));
+
+ do {
+ if (v1.isNumber() && v2.isNumber())
+ return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
+
+ bool s1 = v1.isString();
+ bool s2 = v2.isString();
+ if (s1 && s2)
+ return asString(v1)->value() == asString(v2)->value();
+
+ if (v1.isUndefinedOrNull()) {
+ if (v2.isUndefinedOrNull())
+ return true;
+ if (JSImmediate::isImmediate(v2))
+ return false;
+ return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ }
+
+ if (v2.isUndefinedOrNull()) {
+ if (JSImmediate::isImmediate(v1))
+ return false;
+ return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ }
+
+ if (v1.isObject()) {
+ if (v2.isObject())
+ return v1 == v2;
+ JSValue p1 = v1.toPrimitive(exec);
+ if (exec->hadException())
+ return false;
+ v1 = p1;
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+ continue;
+ }
+
+ if (v2.isObject()) {
+ JSValue p2 = v2.toPrimitive(exec);
+ if (exec->hadException())
+ return false;
+ v2 = p2;
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+ continue;
+ }
+
+ if (s1 || s2) {
+ double d1 = v1.toNumber(exec);
+ double d2 = v2.toNumber(exec);
+ return d1 == d2;
+ }
+
+ if (v1.isBoolean()) {
+ if (v2.isNumber())
+ return static_cast<double>(v1.getBoolean()) == v2.uncheckedGetNumber();
+ } else if (v2.isBoolean()) {
+ if (v1.isNumber())
+ return v1.uncheckedGetNumber() == static_cast<double>(v2.getBoolean());
+ }
+
+ return v1 == v2;
+ } while (true);
+ }
+
+ // ECMA 11.9.3
+ ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(JSValue v1, JSValue v2)
+ {
+ ASSERT(!JSImmediate::isEitherImmediate(v1, v2));
+
+ if (v1.asCell()->isString() && v2.asCell()->isString())
+ return asString(v1)->value() == asString(v2)->value();
+
+ return v1 == v2;
+ }
+
+ inline bool JSValue::strictEqual(JSValue v1, JSValue v2)
+ {
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+
+ if (v1.isNumber() && v2.isNumber())
+ return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
+
+ if (JSImmediate::isEitherImmediate(v1, v2))
+ return v1 == v2;
+
+ return strictEqualSlowCaseInline(v1, v2);
+ }
+
+ inline bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
+ {
+ if (JSValue::areBothInt32Fast(v1, v2))
+ return v1.getInt32Fast() < v2.getInt32Fast();
+
+ double n1;
+ double n2;
+ if (v1.getNumber(n1) && v2.getNumber(n2))
+ return n1 < n2;
+
+ JSGlobalData* globalData = &callFrame->globalData();
+ if (isJSString(globalData, v1) && isJSString(globalData, v2))
+ return asString(v1)->value() < asString(v2)->value();
+
+ JSValue p1;
+ JSValue p2;
+ bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+
+ if (wasNotString1 | wasNotString2)
+ return n1 < n2;
+
+ return asString(p1)->value() < asString(p2)->value();
+ }
+
+ inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
+ {
+ if (JSValue::areBothInt32Fast(v1, v2))
+ return v1.getInt32Fast() <= v2.getInt32Fast();
+
+ double n1;
+ double n2;
+ if (v1.getNumber(n1) && v2.getNumber(n2))
+ return n1 <= n2;
+
+ JSGlobalData* globalData = &callFrame->globalData();
+ if (isJSString(globalData, v1) && isJSString(globalData, v2))
+ return !(asString(v2)->value() < asString(v1)->value());
+
+ JSValue p1;
+ JSValue p2;
+ bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+
+ if (wasNotString1 | wasNotString2)
+ return n1 <= n2;
+
+ return !(asString(p2)->value() < asString(p1)->value());
+ }
+
+ // Fast-path choices here are based on frequency data from SunSpider:
+ // <times> Add case: <t1> <t2>
+ // ---------------------------
+ // 5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
+ // 247412 Add case: 5 5
+ // 20900 Add case: 5 6
+ // 13962 Add case: 5 3
+ // 4000 Add case: 3 5
+
+ ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
+ {
+ double left;
+ double right = 0.0;
+
+ bool rightIsNumber = v2.getNumber(right);
+ if (rightIsNumber && v1.getNumber(left))
+ return jsNumber(callFrame, left + right);
+
+ bool leftIsString = v1.isString();
+ if (leftIsString && v2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
+ }
+
+ if (rightIsNumber & leftIsString) {
+ RefPtr<UString::Rep> value = v2.isInt32Fast() ?
+ concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
+ concatenate(asString(v1)->value().rep(), right);
+
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
+ }
+
+ // All other cases are pretty uncommon
+ return jsAddSlowCase(callFrame, v1, v2);
+ }
+
+ inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot)
+ {
+ JSCell* cell = asCell(baseValue);
+ size_t count = 0;
+
+ while (slot.slotBase() != cell) {
+ JSValue v = cell->structure()->prototypeForLookup(callFrame);
+
+ // If we didn't find slotBase in baseValue's prototype chain, then baseValue
+ // must be a proxy for another object.
+
+ if (v.isNull())
+ return 0;
+
+ cell = asCell(v);
+
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (cell->structure()->isDictionary())
+ asObject(cell)->setStructure(Structure::fromDictionaryTransition(cell->structure()));
+
+ ++count;
+ }
+
+ ASSERT(count);
+ return count;
+ }
+
+ ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+ {
+ ScopeChainIterator iter = scopeChain->begin();
+ ScopeChainIterator next = iter;
+ ++next;
+ ScopeChainIterator end = scopeChain->end();
+ ASSERT(iter != end);
+
+ PropertySlot slot;
+ JSObject* base;
+ while (true) {
+ base = *iter;
+ if (next == end || base->getPropertySlot(callFrame, property, slot))
+ return base;
+
+ iter = next;
+ ++next;
+ }
+
+ ASSERT_NOT_REACHED();
+ return JSValue();
+ }
+
+ ALWAYS_INLINE JSValue concatenateStrings(CallFrame* callFrame, Register* strings, unsigned count)
+ {
+ ASSERT(count >= 3);
+
+ // Estimate the amount of space required to hold the entire string. If all
+ // arguments are strings, we can easily calculate the exact amount of space
+ // required. For any other arguments, for now let's assume they may require
+ // 11 UChars of storage. This is enouch to hold any int, and likely is also
+ // reasonable for the other immediates. We may want to come back and tune
+ // this value at some point.
+ unsigned bufferSize = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ JSValue v = strings[i].jsValue();
+ if (LIKELY(v.isString()))
+ bufferSize += asString(v)->value().size();
+ else
+ bufferSize += 11;
+ }
+
+ // Allocate an output string to store the result.
+ // If the first argument is a String, and if it has the capacity (or can grow
+ // its capacity) to hold the entire result then use this as a base to concatenate
+ // onto. Otherwise, allocate a new empty output buffer.
+ JSValue firstValue = strings[0].jsValue();
+ RefPtr<UString::Rep> resultRep;
+ if (firstValue.isString() && (resultRep = asString(firstValue)->value().rep())->reserveCapacity(bufferSize)) {
+ // We're going to concatenate onto the first string - remove it from the list of items to be appended.
+ ++strings;
+ --count;
+ } else
+ resultRep = UString::Rep::createEmptyBuffer(bufferSize);
+ UString result(resultRep);
+
+ // Loop over the openards, writing them into the output buffer.
+ for (unsigned i = 0; i < count; ++i) {
+ JSValue v = strings[i].jsValue();
+ if (LIKELY(v.isString()))
+ result.append(asString(v)->value());
+ else if (v.isInt32Fast())
+ result.appendNumeric(v.getInt32Fast());
+ else {
+ double d;
+ if (v.getNumber(d))
+ result.appendNumeric(d);
+ else
+ result.append(v.toString(callFrame));
+ }
+ }
+
+ return jsString(callFrame, result);
+ }
+
+} // namespace JSC
+
+#endif // Operations_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h
new file mode 100644
index 0000000..44dc2b8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -0,0 +1,90 @@
+/*
+ * 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"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+ struct PropertyMapEntry {
+ UString::Rep* key;
+ unsigned offset;
+ unsigned attributes;
+ JSCell* specificValue;
+ unsigned index;
+
+ PropertyMapEntry(UString::Rep* key, unsigned attributes, JSCell* specificValue)
+ : key(key)
+ , offset(0)
+ , attributes(attributes)
+ , specificValue(specificValue)
+ , index(0)
+ {
+ }
+
+ PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index)
+ : key(key)
+ , offset(offset)
+ , attributes(attributes)
+ , specificValue(specificValue)
+ , index(index)
+ {
+ }
+ };
+
+ // 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;
+ Vector<unsigned>* deletedOffsets;
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp
new file mode 100644
index 0000000..0878e73
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h
new file mode 100644
index 0000000..67ee9c8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h
@@ -0,0 +1,113 @@
+/*
+ * 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 "CallFrame.h"
+#include "Identifier.h"
+#include "Structure.h"
+#include "StructureChain.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 setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
+ Structure* cachedStructure() const { return m_cachedStructure; }
+
+ void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+ StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
+
+ private:
+ PropertyNameArrayData()
+ : m_cachedStructure(0)
+ {
+ }
+
+ PropertyNameVector m_propertyNameVector;
+ Structure* m_cachedStructure;
+ RefPtr<StructureChain> m_cachedPrototypeChain;
+ };
+
+ class PropertyNameArray {
+ public:
+ typedef PropertyNameArrayData::const_iterator const_iterator;
+
+ PropertyNameArray(JSGlobalData* globalData)
+ : m_data(PropertyNameArrayData::create())
+ , m_globalData(globalData)
+ , m_shouldCache(true)
+ {
+ }
+
+ PropertyNameArray(ExecState* exec)
+ : m_data(PropertyNameArrayData::create())
+ , m_globalData(&exec->globalData())
+ , m_shouldCache(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 setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; }
+ bool shouldCache() const { return m_shouldCache; }
+
+ private:
+ typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
+
+ RefPtr<PropertyNameArrayData> m_data;
+ IdentifierSet m_set;
+ JSGlobalData* m_globalData;
+ bool m_shouldCache;
+ };
+
+} // namespace JSC
+
+#endif // PropertyNameArray_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.cpp
new file mode 100644
index 0000000..36fa5d8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h
new file mode 100644
index 0000000..da0d152
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertySlot.h
@@ -0,0 +1,203 @@
+/*
+ * 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 "Identifier.h"
+#include "JSValue.h"
+#include "JSImmediate.h"
+#include "Register.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(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();
+ 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();
+ 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 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 = JSValue();
+#endif
+ }
+
+ void clearValue()
+ {
+#ifndef NDEBUG
+ m_value = JSValue();
+#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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h
new file mode 100644
index 0000000..6e7984c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 Protect_h
+#define Protect_h
+
+#include "JSCell.h"
+#include "Collector.h"
+
+namespace JSC {
+
+ inline void gcProtect(JSCell* val)
+ {
+ Heap::heap(val)->protect(val);
+ }
+
+ inline void gcUnprotect(JSCell* val)
+ {
+ Heap::heap(val)->unprotect(val);
+ }
+
+ inline void gcProtectNullTolerant(JSCell* val)
+ {
+ if (val)
+ gcProtect(val);
+ }
+
+ inline void gcUnprotectNullTolerant(JSCell* val)
+ {
+ if (val)
+ gcUnprotect(val);
+ }
+
+ inline void gcProtect(JSValue value)
+ {
+ if (value && value.isCell())
+ gcProtect(asCell(value));
+ }
+
+ inline void gcUnprotect(JSValue value)
+ {
+ if (value && value.isCell())
+ gcUnprotect(asCell(value));
+ }
+
+ // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
+ // and the implicit conversion to raw pointer
+ template <class T> class ProtectedPtr {
+ public:
+ ProtectedPtr() : m_ptr(0) {}
+ ProtectedPtr(T* ptr);
+ ProtectedPtr(const ProtectedPtr&);
+ ~ProtectedPtr();
+
+ template <class U> ProtectedPtr(const ProtectedPtr<U>&);
+
+ T* get() const { return m_ptr; }
+ operator T*() const { return m_ptr; }
+ operator JSValue() const { return JSValue(m_ptr); }
+ T* operator->() const { return m_ptr; }
+
+ operator bool() const { return m_ptr; }
+ bool operator!() const { return !m_ptr; }
+
+ ProtectedPtr& operator=(const ProtectedPtr&);
+ ProtectedPtr& operator=(T*);
+
+ private:
+ T* m_ptr;
+ };
+
+ class ProtectedJSValue {
+ public:
+ ProtectedJSValue() {}
+ ProtectedJSValue(JSValue value);
+ ProtectedJSValue(const ProtectedJSValue&);
+ ~ProtectedJSValue();
+
+ template <class U> ProtectedJSValue(const ProtectedPtr<U>&);
+
+ JSValue get() const { return m_value; }
+ operator JSValue() const { return m_value; }
+ //JSValue operator->() const { return m_value; }
+
+ operator bool() const { return m_value; }
+ bool operator!() const { return !m_value; }
+
+ ProtectedJSValue& operator=(const ProtectedJSValue&);
+ ProtectedJSValue& operator=(JSValue);
+
+ private:
+ JSValue m_value;
+ };
+
+ template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr)
+ : m_ptr(ptr)
+ {
+ gcProtectNullTolerant(m_ptr);
+ }
+
+ template <class T> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o)
+ : m_ptr(o.get())
+ {
+ gcProtectNullTolerant(m_ptr);
+ }
+
+ template <class T> inline ProtectedPtr<T>::~ProtectedPtr()
+ {
+ gcUnprotectNullTolerant(m_ptr);
+ }
+
+ template <class T> template <class U> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o)
+ : m_ptr(o.get())
+ {
+ gcProtectNullTolerant(m_ptr);
+ }
+
+ template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o)
+ {
+ T* optr = o.m_ptr;
+ gcProtectNullTolerant(optr);
+ gcUnprotectNullTolerant(m_ptr);
+ m_ptr = optr;
+ return *this;
+ }
+
+ template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr)
+ {
+ gcProtectNullTolerant(optr);
+ gcUnprotectNullTolerant(m_ptr);
+ m_ptr = optr;
+ return *this;
+ }
+
+ inline ProtectedJSValue::ProtectedJSValue(JSValue value)
+ : m_value(value)
+ {
+ gcProtect(m_value);
+ }
+
+ inline ProtectedJSValue::ProtectedJSValue(const ProtectedJSValue& o)
+ : m_value(o.get())
+ {
+ gcProtect(m_value);
+ }
+
+ inline ProtectedJSValue::~ProtectedJSValue()
+ {
+ gcUnprotect(m_value);
+ }
+
+ template <class U> ProtectedJSValue::ProtectedJSValue(const ProtectedPtr<U>& o)
+ : m_value(o.get())
+ {
+ gcProtect(m_value);
+ }
+
+ inline ProtectedJSValue& ProtectedJSValue::operator=(const ProtectedJSValue& o)
+ {
+ JSValue ovalue = o.m_value;
+ gcProtect(ovalue);
+ gcUnprotect(m_value);
+ m_value = ovalue;
+ return *this;
+ }
+
+ inline ProtectedJSValue& ProtectedJSValue::operator=(JSValue ovalue)
+ {
+ gcProtect(ovalue);
+ gcUnprotect(m_value);
+ m_value = ovalue;
+ return *this;
+ }
+
+ template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); }
+ template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; }
+ template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); }
+
+ template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); }
+ template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
+ template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
+
+ inline bool operator==(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() == b.get(); }
+ inline bool operator==(const ProtectedJSValue& a, const JSValue b) { return a.get() == b; }
+ template <class T> inline bool operator==(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() == JSValue(b.get()); }
+ inline bool operator==(const JSValue a, const ProtectedJSValue& b) { return a == b.get(); }
+ template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) == b.get(); }
+
+ inline bool operator!=(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() != b.get(); }
+ inline bool operator!=(const ProtectedJSValue& a, const JSValue b) { return a.get() != b; }
+ template <class T> inline bool operator!=(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() != JSValue(b.get()); }
+ inline bool operator!=(const JSValue a, const ProtectedJSValue& b) { return a != b.get(); }
+ template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) != b.get(); }
+
+} // namespace JSC
+
+#endif // Protect_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp
new file mode 100644
index 0000000..8e3d107
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "PrototypeFunction.h"
+
+#include "JSGlobalObject.h"
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(PrototypeFunction);
+
+PrototypeFunction::PrototypeFunction(ExecState* exec, int length, const Identifier& name, NativeFunction function)
+ : InternalFunction(&exec->globalData(), exec->lexicalGlobalObject()->prototypeFunctionStructure(), name)
+ , m_function(function)
+{
+ ASSERT_ARG(function, function);
+ putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+}
+
+PrototypeFunction::PrototypeFunction(ExecState* exec, PassRefPtr<Structure> 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h
new file mode 100644
index 0000000..99ab327
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2007 Maks Orlovich
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef PrototypeFunction_h
+#define PrototypeFunction_h
+
+#include "InternalFunction.h"
+#include "CallData.h"
+
+namespace JSC {
+
+ class PrototypeFunction : public InternalFunction {
+ public:
+ PrototypeFunction(ExecState*, int length, const Identifier&, NativeFunction);
+ PrototypeFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
+
+ private:
+ virtual CallType getCallData(CallData&);
+
+ const NativeFunction m_function;
+ };
+
+} // namespace JSC
+
+#endif // PrototypeFunction_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PutPropertySlot.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PutPropertySlot.h
new file mode 100644
index 0000000..eb8ea8a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PutPropertySlot.h
@@ -0,0 +1,77 @@
+// -*- 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 JSFunction;
+
+ class PutPropertySlot {
+ public:
+ enum Type { Uncachable, ExistingProperty, NewProperty };
+
+ PutPropertySlot()
+ : m_type(Uncachable)
+ , m_base(0)
+ {
+ }
+
+ 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 != Uncachable; }
+ size_t cachedOffset() const {
+ ASSERT(isCacheable());
+ return m_offset;
+ }
+ private:
+ Type m_type;
+ JSObject* m_base;
+ size_t m_offset;
+ };
+
+} // namespace JSC
+
+#endif // PutPropertySlot_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp
new file mode 100644
index 0000000..b366b58
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
+ * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * 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 "RegExp.h"
+#include "Lexer.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wtf/Assertions.h>
+#include <wtf/OwnArrayPtr.h>
+
+
+#if ENABLE(YARR)
+
+#include "yarr/RegexCompiler.h"
+#if ENABLE(YARR_JIT)
+#include "yarr/RegexJIT.h"
+#else
+#include "yarr/RegexInterpreter.h"
+#endif
+
+#else
+
+#if ENABLE(WREC)
+#include "JIT.h"
+#include "WRECGenerator.h"
+#endif
+#include <pcre/pcre.h>
+
+#endif
+
+namespace JSC {
+
+#if ENABLE(WREC)
+using namespace WREC;
+#endif
+
+inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
+ : m_pattern(pattern)
+ , m_flagBits(0)
+ , m_constructionError(0)
+ , m_numSubpatterns(0)
+{
+ compile(globalData);
+}
+
+inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
+ : m_pattern(pattern)
+ , m_flags(flags)
+ , m_flagBits(0)
+ , m_constructionError(0)
+ , m_numSubpatterns(0)
+{
+ // NOTE: The global flag is handled on a case-by-case basis by functions like
+ // String::match and RegExpObject::match.
+#ifndef QT_BUILD_SCRIPT_LIB
+ if (flags.find('g') != -1)
+ m_flagBits |= Global;
+ if (flags.find('i') != -1)
+ m_flagBits |= IgnoreCase;
+ if (flags.find('m') != -1)
+ m_flagBits |= Multiline;
+#else //Invalid flags should throw a SyntaxError (ECMA Script 15.10.4.1)
+ static const char flagError[] = "invalid regular expression flag";
+ for (int i = 0; i < flags.size(); i++) {
+ switch (flags.data()[i]) {
+ case 'g':
+ m_flagBits |= Global;
+ break;
+ case 'i':
+ m_flagBits |= IgnoreCase;
+ break;
+ case 'm':
+ m_flagBits |= Multiline;
+ break;
+ default:
+ m_constructionError = flagError;
+#if !ENABLE(YARR)
+ m_regExp = 0;
+#endif
+ return;
+ }
+ }
+#endif
+
+ compile(globalData);
+}
+
+#if !ENABLE(YARR)
+RegExp::~RegExp()
+{
+ jsRegExpFree(m_regExp);
+}
+#endif
+
+PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
+{
+ return adoptRef(new RegExp(globalData, pattern));
+}
+
+PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
+{
+ return adoptRef(new RegExp(globalData, pattern, flags));
+}
+
+#if ENABLE(YARR)
+
+void RegExp::compile(JSGlobalData* globalData)
+{
+#if ENABLE(YARR_JIT)
+ Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
+#else
+ UNUSED_PARAM(globalData);
+ m_regExpBytecode.set(Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline()));
+#endif
+}
+
+int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
+{
+ if (startOffset < 0)
+ startOffset = 0;
+ if (ovector)
+ ovector->clear();
+
+ if (startOffset > s.size() || s.isNull())
+ return -1;
+
+#if ENABLE(YARR_JIT)
+ if (!!m_regExpJITCode) {
+#else
+ if (m_regExpBytecode) {
+#endif
+ int offsetVectorSize = (m_numSubpatterns + 1) * 3; // FIXME: should be 2 - but adding temporary fallback to pcre.
+ int* offsetVector;
+ Vector<int, 32> nonReturnedOvector;
+ if (ovector) {
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ } else {
+ nonReturnedOvector.resize(offsetVectorSize);
+ offsetVector = nonReturnedOvector.data();
+ }
+
+ ASSERT(offsetVector);
+ for (int j = 0; j < offsetVectorSize; ++j)
+ offsetVector[j] = -1;
+
+
+#if ENABLE(YARR_JIT)
+ int result = Yarr::executeRegex(m_regExpJITCode, s.data(), startOffset, s.size(), offsetVector, offsetVectorSize);
+#else
+ int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.data(), startOffset, s.size(), offsetVector);
+#endif
+
+ if (result < 0) {
+#ifndef NDEBUG
+ // TODO: define up a symbol, rather than magic -1
+ if (result != -1)
+ fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
+#endif
+ if (ovector)
+ ovector->clear();
+ }
+ return result;
+ }
+
+ return -1;
+}
+
+#else
+
+void RegExp::compile(JSGlobalData* globalData)
+{
+ m_regExp = 0;
+#if ENABLE(WREC)
+ m_wrecFunction = Generator::compileRegExp(globalData, m_pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, ignoreCase(), multiline());
+ if (m_wrecFunction || m_constructionError)
+ return;
+ // Fall through to non-WREC case.
+#else
+ UNUSED_PARAM(globalData);
+#endif
+
+ JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
+ JSRegExpMultilineOption multilineOption = multiline() ? JSRegExpMultiline : JSRegExpSingleLine;
+ m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.data()), m_pattern.size(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
+}
+
+int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
+{
+ if (startOffset < 0)
+ startOffset = 0;
+ if (ovector)
+ ovector->clear();
+
+ if (startOffset > s.size() || s.isNull())
+ return -1;
+
+#if ENABLE(WREC)
+ if (m_wrecFunction) {
+ int offsetVectorSize = (m_numSubpatterns + 1) * 2;
+ int* offsetVector;
+ Vector<int, 32> nonReturnedOvector;
+ if (ovector) {
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ } else {
+ nonReturnedOvector.resize(offsetVectorSize);
+ offsetVector = nonReturnedOvector.data();
+ }
+ ASSERT(offsetVector);
+ for (int j = 0; j < offsetVectorSize; ++j)
+ offsetVector[j] = -1;
+
+ int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
+
+ if (result < 0) {
+#ifndef NDEBUG
+ // TODO: define up a symbol, rather than magic -1
+ if (result != -1)
+ fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
+#endif
+ if (ovector)
+ ovector->clear();
+ }
+ return result;
+ } else
+#endif
+ if (m_regExp) {
+ // Set up the offset vector for the result.
+ // First 2/3 used for result, the last third used by PCRE.
+ int* offsetVector;
+ int offsetVectorSize;
+ int fixedSizeOffsetVector[3];
+ if (!ovector) {
+ offsetVectorSize = 3;
+ offsetVector = fixedSizeOffsetVector;
+ } else {
+ offsetVectorSize = (m_numSubpatterns + 1) * 3;
+ ovector->resize(offsetVectorSize);
+ offsetVector = ovector->data();
+ }
+
+ int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize);
+
+ if (numMatches < 0) {
+#ifndef NDEBUG
+ if (numMatches != JSRegExpErrorNoMatch)
+ fprintf(stderr, "jsRegExpExecute failed with result %d\n", numMatches);
+#endif
+ if (ovector)
+ ovector->clear();
+ return -1;
+ }
+
+ return offsetVector[0];
+ }
+
+ return -1;
+}
+
+#endif
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h
new file mode 100644
index 0000000..24d4199
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * 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 RegExp_h
+#define RegExp_h
+
+#include "UString.h"
+#include "WREC.h"
+#include "ExecutableAllocator.h"
+#include <wtf/Forward.h>
+#include <wtf/RefCounted.h>
+#include "yarr/RegexJIT.h"
+#include "yarr/RegexInterpreter.h"
+
+struct JSRegExp;
+
+namespace JSC {
+
+ class JSGlobalData;
+
+ class RegExp : public RefCounted<RegExp> {
+ public:
+ static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern);
+ static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+#if !ENABLE(YARR)
+ ~RegExp();
+#endif
+
+ bool global() const { return m_flagBits & Global; }
+ bool ignoreCase() const { return m_flagBits & IgnoreCase; }
+ bool multiline() const { return m_flagBits & Multiline; }
+
+ const UString& pattern() const { return m_pattern; }
+ const UString& flags() const { return m_flags; }
+
+ bool isValid() const { return !m_constructionError; }
+ const char* errorMessage() const { return m_constructionError; }
+
+ int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
+ unsigned numSubpatterns() const { return m_numSubpatterns; }
+
+ private:
+ RegExp(JSGlobalData* globalData, const UString& pattern);
+ RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+
+ void compile(JSGlobalData*);
+
+ enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
+
+ UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
+ UString m_flags; // FIXME: Just decompile m_regExp instead of storing this.
+ int m_flagBits;
+ const char* m_constructionError;
+ unsigned m_numSubpatterns;
+
+#if ENABLE(YARR_JIT)
+ Yarr::RegexCodeBlock m_regExpJITCode;
+#elif ENABLE(YARR)
+ OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
+#else
+#if ENABLE(WREC)
+ WREC::CompiledRegExp m_wrecFunction;
+ RefPtr<ExecutablePool> m_executablePool;
+#endif
+ JSRegExp* m_regExp;
+#endif
+ };
+
+} // namespace JSC
+
+#endif // RegExp_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp
new file mode 100644
index 0000000..e468521
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * 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)
+ , lastOvectorIndex(0)
+ {
+ }
+
+ const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; }
+ Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; }
+ Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; }
+ void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; }
+
+ UString input;
+ UString lastInput;
+ Vector<int, 32> ovector[2];
+ unsigned lastNumSubPatterns : 30;
+ bool multiline : 1;
+ unsigned lastOvectorIndex : 1;
+};
+
+RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> 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)
+{
+ position = r->match(s, startOffset, &d->tempOvector());
+
+ if (ovector)
+ *ovector = d->tempOvector().data();
+
+ if (position != -1) {
+ ASSERT(!d->tempOvector().isEmpty());
+
+ length = d->tempOvector()[1] - d->tempOvector()[0];
+
+ d->input = s;
+ d->lastInput = s;
+ d->changeLastOvector();
+ d->lastNumSubPatterns = r->numSubpatterns();
+ }
+}
+
+RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
+ : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1)
+{
+ 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().resize(offsetVectorSize);
+ memcpy(d->lastOvector().data(), data->lastOvector().data(), 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().isEmpty() && 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().isEmpty());
+ 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().isEmpty())
+ return jsSubstring(exec, d->lastInput, 0, d->lastOvector()[0]);
+ return jsEmptyString(exec);
+}
+
+JSValue RegExpConstructor::getRightContext(ExecState* exec) const
+{
+ if (!d->lastOvector().isEmpty())
+ 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(0);
+ JSValue arg1 = args.at(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 JSC_HOST_CALL 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h
new file mode 100644
index 0000000..6823f3f
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef RegExpConstructor_h
+#define RegExpConstructor_h
+
+#include "InternalFunction.h"
+#include <wtf/OwnPtr.h>
+
+namespace JSC {
+
+ class RegExp;
+ class RegExpPrototype;
+ struct RegExpConstructorPrivate;
+
+ class RegExpConstructor : public InternalFunction {
+ public:
+ RegExpConstructor(ExecState*, PassRefPtr<Structure>, RegExpPrototype*);
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h
new file mode 100644
index 0000000..cbba85a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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, bool checkDontDelete = true)
+ {
+ if (lazyCreationData())
+ fillArrayInstance(exec);
+ return JSArray::deleteProperty(exec, propertyName, checkDontDelete);
+ }
+
+ virtual bool deleteProperty(ExecState* exec, unsigned propertyName, bool checkDontDelete = true)
+ {
+ if (lazyCreationData())
+ fillArrayInstance(exec);
+ return JSArray::deleteProperty(exec, propertyName, checkDontDelete);
+ }
+
+ virtual void getPropertyNames(ExecState* exec, PropertyNameArray& arr, unsigned listedAttributes)
+ {
+ if (lazyCreationData())
+ fillArrayInstance(exec);
+ JSArray::getPropertyNames(exec, arr, listedAttributes);
+ }
+
+ void fillArrayInstance(ExecState*);
+};
+
+}
+
+#endif // RegExpMatchesArray_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp
new file mode 100644
index 0000000..687844e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "RegExpObject.h"
+
+#include "Error.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<Structure> 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));
+}
+
+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 JSC_HOST_CALL 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;
+}
+
+// Shared implementation used by test and exec.
+bool RegExpObject::match(ExecState* exec, const ArgList& args)
+{
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+
+ UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
+ if (input.isNull()) {
+ throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
+ return false;
+ }
+
+ if (!regExp()->global()) {
+ int position;
+ int length;
+ regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length);
+ return position >= 0;
+ }
+
+ if (d->lastIndex < 0 || d->lastIndex > input.size()) {
+ d->lastIndex = 0;
+ return false;
+ }
+
+ int position;
+ int length;
+ regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
+ if (position < 0) {
+ d->lastIndex = 0;
+ return false;
+ }
+
+ d->lastIndex = position + length;
+ return true;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h
new file mode 100644
index 0000000..fac9978
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef RegExpObject_h
+#define RegExpObject_h
+
+#include "JSObject.h"
+#include "RegExp.h"
+
+namespace JSC {
+
+ class RegExpObject : public JSObject {
+ public:
+ RegExpObject(PassRefPtr<Structure>, 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<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp
new file mode 100644
index 0000000..e507016
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "RegExpPrototype.h"
+
+#include "ArrayPrototype.h"
+#include "JSArray.h"
+#include "JSFunction.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 JSC_HOST_CALL regExpProtoFuncTest(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+
+// ECMA 15.10.5
+
+const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
+
+RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+ : JSObject(structure)
+{
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
+}
+
+// ------------------------------ Functions ---------------------------
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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(0);
+ JSValue arg1 = args.at(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 JSC_HOST_CALL 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);
+#ifdef QT_BUILD_SCRIPT_LIB
+ if (result.size() == 1)
+ result.append("(?:)");
+#endif
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h
new file mode 100644
index 0000000..f5db720
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef RegExpPrototype_h
+#define RegExpPrototype_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ class RegExpPrototype : public JSObject {
+ public:
+ RegExpPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const ClassInfo info;
+ };
+
+} // namespace JSC
+
+#endif // RegExpPrototype_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp
new file mode 100644
index 0000000..5c2edab
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "JSActivation.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
+
+int ScopeChain::localDepth() const
+{
+ int scopeDepth = 0;
+ ScopeChainIterator iter = this->begin();
+ ScopeChainIterator end = this->end();
+ while (!(*iter)->isObject(&JSActivation::info)) {
+ ++iter;
+ if (iter == end)
+ break;
+ ++scopeDepth;
+ }
+ return scopeDepth;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h
new file mode 100644
index 0000000..17aff24
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h
@@ -0,0 +1,240 @@
+/*
+ * 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 "FastAllocBase.h"
+
+namespace JSC {
+
+ class JSGlobalData;
+ class JSGlobalObject;
+ class JSObject;
+ class ScopeChainIterator;
+
+ class ScopeChainNode : public FastAllocBase {
+ public:
+ ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSObject* globalThis)
+ : next(next)
+ , object(object)
+ , globalData(globalData)
+ , globalThis(globalThis)
+ , refCount(1)
+ {
+ ASSERT(globalData);
+ }
+#ifndef NDEBUG
+ // Due to the number of subtle and timing dependent bugs that have occurred due
+ // to deleted but still "valid" ScopeChainNodes we now deliberately clobber the
+ // contents in debug builds.
+ ~ScopeChainNode()
+ {
+ next = 0;
+ object = 0;
+ globalData = 0;
+ globalThis = 0;
+ }
+#endif
+
+ ScopeChainNode* next;
+ JSObject* object;
+ JSGlobalData* globalData;
+ JSObject* globalThis;
+ int refCount;
+
+ void deref() { ASSERT(refCount); if (--refCount == 0) { release();} }
+ void ref() { ASSERT(refCount); ++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 JIT;
+ 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();
+#ifndef NDEBUG
+ m_node = 0;
+#endif
+ }
+
+ 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;
+
+ // Caution: this should only be used if the codeblock this is being used
+ // with needs a full scope chain, otherwise this returns the depth of
+ // the preceeding call frame
+ //
+ // Returns the depth of the current call frame's scope chain
+ int localDepth() 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChainMark.h
new file mode 100644
index 0000000..b80b8ef
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp
new file mode 100644
index 0000000..9d1f01a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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"
+
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+static const unsigned numCharactersToStore = 0x100;
+
+class SmallStringsStorage : public Noncopyable {
+public:
+ SmallStringsStorage();
+
+ UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
+
+private:
+ UChar m_characters[numCharactersToStore];
+ UString::BaseString m_base;
+ UString::Rep m_reps[numCharactersToStore];
+};
+
+SmallStringsStorage::SmallStringsStorage()
+ : m_base(m_characters, numCharactersToStore)
+{
+ m_base.rc = numCharactersToStore + 1;
+ // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
+ m_base.usedCapacity = numCharactersToStore + 1;
+ m_base.capacity = numCharactersToStore + 1;
+ m_base.checkConsistency();
+
+ for (unsigned i = 0; i < numCharactersToStore; ++i)
+ m_characters[i] = i;
+
+ memset(&m_reps, 0, sizeof(m_reps));
+ for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ m_reps[i].offset = i;
+ m_reps[i].len = 1;
+ m_reps[i].rc = 1;
+ m_reps[i].setBaseString(&m_base);
+ m_reps[i].checkConsistency();
+ }
+}
+
+SmallStrings::SmallStrings()
+ : m_emptyString(0)
+ , m_storage(0)
+{
+ COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
+
+ for (unsigned i = 0; i < numCharactersToStore; ++i)
+ m_singleCharacterStrings[i] = 0;
+}
+
+SmallStrings::~SmallStrings()
+{
+}
+
+void SmallStrings::mark()
+{
+ if (m_emptyString && !m_emptyString->marked())
+ m_emptyString->mark();
+ for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked())
+ m_singleCharacterStrings[i]->mark();
+ }
+}
+
+unsigned SmallStrings::count() const
+{
+ unsigned count = 0;
+ if (m_emptyString)
+ ++count;
+ for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ if (m_singleCharacterStrings[i])
+ ++count;
+ }
+ return count;
+}
+
+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);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h
new file mode 100644
index 0000000..f0dd8df
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.h
@@ -0,0 +1,74 @@
+/*
+ * 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 : public 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();
+
+ unsigned count() const;
+
+ private:
+ void createEmptyString(JSGlobalData*);
+ void createSingleCharacterString(JSGlobalData*, unsigned char);
+
+ JSString* m_emptyString;
+ JSString* m_singleCharacterStrings[0x100];
+ OwnPtr<SmallStringsStorage> m_storage;
+ };
+
+} // namespace JSC
+
+#endif // SmallStrings_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp
new file mode 100644
index 0000000..6380445
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "StringConstructor.h"
+
+#include "JSFunction.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).toUInt32(exec));
+ return jsString(exec, UString(buf, p - buf, false));
+}
+
+static JSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ if (LIKELY(args.size() == 1))
+ return jsSingleCharacterString(exec, args.at(0).toUInt32(exec));
+ return stringFromCharCodeSlowCase(exec, args);
+}
+
+ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
+
+StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* 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) NativeFunctionWrapper(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(0).toString(exec));
+}
+
+ConstructType StringConstructor::getConstructData(ConstructData& constructData)
+{
+ constructData.native.function = constructWithStringConstructor;
+ return ConstructTypeHost;
+}
+
+// ECMA 15.5.1
+static JSValue JSC_HOST_CALL callStringConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ if (args.isEmpty())
+ return jsEmptyString(exec);
+ return jsString(exec, args.at(0).toString(exec));
+}
+
+CallType StringConstructor::getCallData(CallData& callData)
+{
+ callData.native.function = callStringConstructor;
+ return CallTypeHost;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h
new file mode 100644
index 0000000..7d52c69
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef StringConstructor_h
+#define StringConstructor_h
+
+#include "InternalFunction.h"
+
+namespace JSC {
+
+ class StringPrototype;
+
+ class StringConstructor : public InternalFunction {
+ public:
+ StringConstructor(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure, StringPrototype*);
+
+ virtual ConstructType getConstructData(ConstructData&);
+ virtual CallType getCallData(CallData&);
+ };
+
+} // namespace JSC
+
+#endif // StringConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp
new file mode 100644
index 0000000..4745a98
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+#include "StringObject.h"
+
+#include "PropertyNameArray.h"
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(StringObject);
+
+const ClassInfo StringObject::info = { "String", 0, 0, 0 };
+
+StringObject::StringObject(ExecState* exec, PassRefPtr<Structure> structure)
+ : JSWrapperObject(structure)
+{
+ setInternalValue(jsEmptyString(exec));
+}
+
+StringObject::StringObject(PassRefPtr<Structure> structure, JSString* string)
+ : JSWrapperObject(structure)
+{
+ setInternalValue(string);
+}
+
+StringObject::StringObject(ExecState* exec, PassRefPtr<Structure> 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, bool checkDontDelete)
+{
+ if (propertyName == exec->propertyNames().length)
+ return false;
+ bool isStrictUInt32;
+ unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
+ if (isStrictUInt32 && internalValue()->canGetIndex(i))
+ return false;
+ return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
+}
+
+void StringObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, unsigned listedAttributes)
+{
+ int size = internalValue()->value().size();
+ for (int i = 0; i < size; ++i)
+ propertyNames.add(Identifier(exec, UString::from(i)));
+ return JSObject::getPropertyNames(exec, propertyNames, listedAttributes);
+}
+
+bool StringObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+{
+ if (internalValue()->getStringPropertyAttributes(exec, propertyName, attributes))
+ return true;
+ return JSObject::getPropertyAttributes(exec, propertyName, attributes);
+}
+
+UString StringObject::toString(ExecState*) const
+{
+ return internalValue()->value();
+}
+
+UString StringObject::toThisString(ExecState*) const
+{
+ return internalValue()->value();
+}
+
+JSString* StringObject::toThisJSString(ExecState*)
+{
+ return internalValue();
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h
new file mode 100644
index 0000000..fdeb2c1
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef StringObject_h
+#define StringObject_h
+
+#include "JSWrapperObject.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ class StringObject : public JSWrapperObject {
+ public:
+ StringObject(ExecState*, PassRefPtr<Structure>);
+ StringObject(ExecState*, PassRefPtr<Structure>, 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, bool checkDontDelete = true);
+ virtual void getPropertyNames(ExecState*, PropertyNameArray&, unsigned listedAttributes = Structure::Prototype);
+ virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+
+ virtual const ClassInfo* classInfo() const { return &info; }
+ static const JS_EXPORTDATA ClassInfo info;
+
+ JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+
+ protected:
+ StringObject(PassRefPtr<Structure>, 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
new file mode 100644
index 0000000..bc5c0a5
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef StringObjectThatMasqueradesAsUndefined_h
+#define StringObjectThatMasqueradesAsUndefined_h
+
+#include "JSGlobalObject.h"
+#include "StringObject.h"
+#include "UString.h"
+
+namespace JSC {
+
+ // WebCore uses this to make style.filter undetectable
+ class StringObjectThatMasqueradesAsUndefined : public StringObject {
+ public:
+ static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string)
+ {
+ return new (exec) StringObjectThatMasqueradesAsUndefined(exec,
+ createStructure(exec->lexicalGlobalObject()->stringPrototype()), string);
+ }
+
+ private:
+ StringObjectThatMasqueradesAsUndefined(ExecState* exec, PassRefPtr<Structure> structure, const UString& string)
+ : StringObject(exec, structure, string)
+ {
+ }
+
+ static PassRefPtr<Structure> createStructure(JSValue proto)
+ {
+ return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined));
+ }
+
+ virtual bool toBoolean(ExecState*) const { return false; }
+ };
+
+} // namespace JSC
+
+#endif // StringObjectThatMasqueradesAsUndefined_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp
new file mode 100644
index 0000000..ceb6b1e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * 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 "CachedCall.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 JSC_HOST_CALL stringProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValue, const ArgList&);
+
+static JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL 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<Structure> 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;
+
+ UChar ref = replacement[i + 1];
+ if (ref == '$') {
+ // "$$" -> "$"
+ ++i;
+ substitutedReplacement.append(replacement.data() + offset, i - offset);
+ offset = i + 1;
+ 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 (reg && 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;
+ }
+ }
+ if (!backrefIndex)
+ continue;
+ 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 JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ JSString* sourceVal = thisValue.toThisJSString(exec);
+ const UString& source = sourceVal->value();
+
+ JSValue pattern = args.at(0);
+
+ JSValue replacement = args.at(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* regExpConstructor = 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).
+ if (global && callType == CallTypeJS) {
+ // reg->numSubpatterns() + 1 for pattern args, + 2 for match start and sourceValue
+ int argCount = reg->numSubpatterns() + 1 + 2;
+ JSFunction* func = asFunction(replacement);
+ CachedCall cachedCall(exec, func, argCount, exec->exceptionSlot());
+ if (exec->hadException())
+ return jsNull();
+ while (true) {
+ int matchIndex;
+ int matchLen;
+ int* ovector;
+ regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
+ if (matchIndex < 0)
+ break;
+
+ sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+
+ int completeMatchStart = ovector[0];
+ unsigned i = 0;
+ for (; i < reg->numSubpatterns() + 1; ++i) {
+ int matchStart = ovector[i * 2];
+ int matchLen = ovector[i * 2 + 1] - matchStart;
+
+ if (matchStart < 0)
+ cachedCall.setArgument(i, jsUndefined());
+ else
+ cachedCall.setArgument(i, jsSubstring(exec, source, matchStart, matchLen));
+ }
+
+ cachedCall.setArgument(i++, jsNumber(exec, completeMatchStart));
+ cachedCall.setArgument(i++, sourceVal);
+
+ cachedCall.setThis(exec->globalThisValue());
+ replacements.append(cachedCall.call().toString(cachedCall.newCallFrame()));
+ if (exec->hadException())
+ break;
+
+ lastIndex = matchIndex + matchLen;
+ startPosition = lastIndex;
+
+ // special case of empty match
+ if (matchLen == 0) {
+ startPosition++;
+ if (startPosition > source.size())
+ break;
+ }
+ }
+ } else {
+ do {
+ int matchIndex;
+ int matchLen;
+ int* ovector;
+ regExpConstructor->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];
+ MarkedArgumentBuffer 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 && replacements.isEmpty())
+ return sourceVal;
+
+ if (lastIndex < source.size())
+ sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+
+ return jsString(exec, source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(),
+ replacements.data(), replacements.size()));
+ }
+
+ // Not a regular expression, so treat the pattern as a string.
+
+ UString patternString = pattern.toString(exec);
+ int matchPos = source.find(patternString);
+
+ if (matchPos == -1)
+ return sourceVal;
+
+ int matchLen = patternString.size();
+ if (callType != CallTypeNone) {
+ MarkedArgumentBuffer 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);
+ }
+
+ int ovector[2] = { matchPos, matchPos + matchLen };
+ return jsString(exec, source.replaceRange(matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0)));
+}
+
+JSValue JSC_HOST_CALL 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 JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ unsigned len = s.size();
+ JSValue a0 = args.at(0);
+ if (a0.isUInt32Fast()) {
+ uint32_t i = a0.getUInt32Fast();
+ if (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 JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ unsigned len = s.size();
+ JSValue a0 = args.at(0);
+ if (a0.isUInt32Fast()) {
+ uint32_t i = a0.getUInt32Fast();
+ if (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 JSC_HOST_CALL 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).toString(exec);
+ return jsString(exec, s);
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ int len = s.size();
+
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(1);
+ UString u2 = a0.toString(exec);
+ int pos;
+ if (a1.isUndefined())
+ pos = 0;
+ else if (a1.isUInt32Fast())
+ pos = min<uint32_t>(a1.getUInt32Fast(), len);
+ else {
+ double dpos = a1.toInteger(exec);
+ if (dpos < 0)
+ dpos = 0;
+ else if (dpos > len)
+ dpos = len;
+ pos = static_cast<int>(dpos);
+ }
+
+ return jsNumber(exec, s.find(u2, pos));
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ int len = s.size();
+
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(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 JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+
+ JSValue a0 = args.at(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* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+ int pos;
+ int matchLength;
+ regExpConstructor->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 regExpConstructor->arrayOfMatches(exec);
+ }
+
+ // return array of matches
+ MarkedArgumentBuffer list;
+ int lastIndex = 0;
+ while (pos >= 0) {
+ list.append(jsSubstring(exec, u, pos, matchLength));
+ lastIndex = pos;
+ pos += matchLength == 0 ? 1 : matchLength;
+ regExpConstructor->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 JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+
+ JSValue a0 = args.at(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* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+ int pos;
+ int matchLength;
+ regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
+ return jsNumber(exec, pos);
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ int len = s.size();
+
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(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 JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(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()) {
+ Vector<int, 32> 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 JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ int len = s.size();
+
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(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 JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ int len = s.size();
+
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(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 JSC_HOST_CALL 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 JSC_HOST_CALL 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 JSC_HOST_CALL 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(0);
+ return jsNumber(exec, localeCompare(s, a0.toString(exec)));
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<big>" + s + "</big>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<small>" + s + "</small>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<blink>" + s + "</blink>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<b>" + s + "</b>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsString(exec, "<tt>" + s + "</tt>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<i>" + s + "</i>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<strike>" + s + "</strike>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<sub>" + s + "</sub>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<sup>" + s + "</sup>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
+ return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
+
+ uint32_t smallInteger;
+ if (a0.getUInt32(smallInteger) && smallInteger <= 9) {
+ unsigned stringSize = s.size();
+ unsigned bufferSize = 22 + stringSize;
+ UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
+ if (!buffer)
+ return jsUndefined();
+ buffer[0] = '<';
+ buffer[1] = 'f';
+ buffer[2] = 'o';
+ buffer[3] = 'n';
+ buffer[4] = 't';
+ buffer[5] = ' ';
+ buffer[6] = 's';
+ buffer[7] = 'i';
+ buffer[8] = 'z';
+ buffer[9] = 'e';
+ buffer[10] = '=';
+ buffer[11] = '"';
+ buffer[12] = '0' + smallInteger;
+ buffer[13] = '"';
+ buffer[14] = '>';
+ memcpy(&buffer[15], s.data(), stringSize * sizeof(UChar));
+ buffer[15 + stringSize] = '<';
+ buffer[16 + stringSize] = '/';
+ buffer[17 + stringSize] = 'f';
+ buffer[18 + stringSize] = 'o';
+ buffer[19 + stringSize] = 'n';
+ buffer[20 + stringSize] = 't';
+ buffer[21 + stringSize] = '>';
+ return jsNontrivialString(exec, UString(buffer, bufferSize, false));
+ }
+
+ return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
+ return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
+ UString linkText = a0.toString(exec);
+
+ unsigned linkTextSize = linkText.size();
+ unsigned stringSize = s.size();
+ unsigned bufferSize = 15 + linkTextSize + stringSize;
+ UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
+ if (!buffer)
+ return jsUndefined();
+ buffer[0] = '<';
+ buffer[1] = 'a';
+ buffer[2] = ' ';
+ buffer[3] = 'h';
+ buffer[4] = 'r';
+ buffer[5] = 'e';
+ buffer[6] = 'f';
+ buffer[7] = '=';
+ buffer[8] = '"';
+ memcpy(&buffer[9], linkText.data(), linkTextSize * sizeof(UChar));
+ buffer[9 + linkTextSize] = '"';
+ buffer[10 + linkTextSize] = '>';
+ memcpy(&buffer[11 + linkTextSize], s.data(), stringSize * sizeof(UChar));
+ buffer[11 + linkTextSize + stringSize] = '<';
+ buffer[12 + linkTextSize + stringSize] = '/';
+ buffer[13 + linkTextSize + stringSize] = 'a';
+ buffer[14 + linkTextSize + stringSize] = '>';
+ return jsNontrivialString(exec, UString(buffer, bufferSize, false));
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h
new file mode 100644
index 0000000..6f5344e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef StringPrototype_h
+#define StringPrototype_h
+
+#include "StringObject.h"
+
+namespace JSC {
+
+ class ObjectPrototype;
+
+ class StringPrototype : public StringObject {
+ public:
+ StringPrototype(ExecState*, PassRefPtr<Structure>);
+
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp
new file mode 100644
index 0000000..38c086e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp
@@ -0,0 +1,1156 @@
+/*
+ * 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 "Structure.h"
+
+#include "Identifier.h"
+#include "JSObject.h"
+#include "PropertyNameArray.h"
+#include "StructureChain.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 namespace WTF;
+
+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;
+
+static const unsigned newTableSize = 16;
+
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter structureCounter("Structure");
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+static Mutex& ignoreSetMutex = *(new Mutex);
+#endif
+
+static bool shouldIgnoreLeaks;
+static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>);
+#endif
+
+#if DUMP_STRUCTURE_ID_STATISTICS
+static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
+#endif
+
+void Structure::dumpStatistics()
+{
+#if DUMP_STRUCTURE_ID_STATISTICS
+ unsigned numberLeaf = 0;
+ unsigned numberUsingSingleSlot = 0;
+ unsigned numberSingletons = 0;
+ unsigned numberWithPropertyMaps = 0;
+ unsigned totalPropertyMapsSize = 0;
+
+ HashSet<Structure*>::const_iterator end = liveStructureSet.end();
+ for (HashSet<Structure*>::const_iterator it = liveStructureSet.begin(); it != end; ++it) {
+ Structure* structure = *it;
+ if (structure->m_usingSingleTransitionSlot) {
+ if (!structure->m_transitions.singleTransition)
+ ++numberLeaf;
+ else
+ ++numberUsingSingleSlot;
+
+ if (!structure->m_previous && !structure->m_transitions.singleTransition)
+ ++numberSingletons;
+ }
+
+ if (structure->m_propertyTable) {
+ ++numberWithPropertyMaps;
+ totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structure->m_propertyTable->size);
+ if (structure->m_propertyTable->deletedOffsets)
+ totalPropertyMapsSize += (structure->m_propertyTable->deletedOffsets->capacity() * sizeof(unsigned));
+ }
+ }
+
+ printf("Number of live Structures: %d\n", liveStructureSet.size());
+ printf("Number of Structures using the single item optimization for transition map: %d\n", numberUsingSingleSlot);
+ printf("Number of Structures that are leaf nodes: %d\n", numberLeaf);
+ printf("Number of Structures that singletons: %d\n", numberSingletons);
+ printf("Number of Structures with PropertyMaps: %d\n", numberWithPropertyMaps);
+
+ printf("Size of a single Structures: %d\n", static_cast<unsigned>(sizeof(Structure)));
+ 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>(liveStructureSet.size()));
+#else
+ printf("Dumping Structure statistics is not enabled.\n");
+#endif
+}
+
+Structure::Structure(JSValue prototype, const TypeInfo& typeInfo)
+ : m_typeInfo(typeInfo)
+ , m_prototype(prototype)
+ , m_specificValueInPrevious(0)
+ , m_propertyTable(0)
+ , m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
+ , m_offset(noOffset)
+ , m_isDictionary(false)
+ , m_isPinnedPropertyTable(false)
+ , m_hasGetterSetterProperties(false)
+ , m_usingSingleTransitionSlot(true)
+ , m_attributesInPrevious(0)
+{
+ ASSERT(m_prototype);
+ ASSERT(m_prototype.isObject() || m_prototype.isNull());
+
+ m_transitions.singleTransition = 0;
+
+#ifndef NDEBUG
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ MutexLocker protect(ignoreSetMutex);
+#endif
+ if (shouldIgnoreLeaks)
+ ignoreSet.add(this);
+ else
+ structureCounter.increment();
+#endif
+
+#if DUMP_STRUCTURE_ID_STATISTICS
+ liveStructureSet.add(this);
+#endif
+}
+
+Structure::~Structure()
+{
+ if (m_previous) {
+ if (m_previous->m_usingSingleTransitionSlot) {
+ m_previous->m_transitions.singleTransition = 0;
+ } else {
+ ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious))));
+ m_previous->m_transitions.table->remove(make_pair<RefPtr<UString::Rep>, std::pair<unsigned,JSCell*> >(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious)));
+ }
+ }
+
+ if (m_cachedPropertyNameArrayData)
+ m_cachedPropertyNameArrayData->setCachedStructure(0);
+
+ if (!m_usingSingleTransitionSlot)
+ delete m_transitions.table;
+
+ if (m_propertyTable) {
+ unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+ for (unsigned i = 1; i <= entryCount; i++) {
+ if (UString::Rep* key = m_propertyTable->entries()[i].key)
+ key->deref();
+ }
+
+ delete m_propertyTable->deletedOffsets;
+ fastFree(m_propertyTable);
+ }
+
+#ifndef NDEBUG
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ MutexLocker protect(ignoreSetMutex);
+#endif
+ HashSet<Structure*>::iterator it = ignoreSet.find(this);
+ if (it != ignoreSet.end())
+ ignoreSet.remove(it);
+ else
+ structureCounter.decrement();
+#endif
+
+#if DUMP_STRUCTURE_ID_STATISTICS
+ liveStructureSet.remove(this);
+#endif
+}
+
+void Structure::startIgnoringLeaks()
+{
+#ifndef NDEBUG
+ shouldIgnoreLeaks = true;
+#endif
+}
+
+void Structure::stopIgnoringLeaks()
+{
+#ifndef NDEBUG
+ shouldIgnoreLeaks = false;
+#endif
+}
+
+static bool isPowerOf2(unsigned v)
+{
+ // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
+
+ return !(v & (v - 1)) && v;
+}
+
+static unsigned nextPowerOf2(unsigned v)
+{
+ // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
+ // Devised by Sean Anderson, Sepember 14, 2001
+
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+
+ return v;
+}
+
+static unsigned sizeForKeyCount(size_t keyCount)
+{
+ if (keyCount == notFound)
+ return newTableSize;
+
+ if (keyCount < 8)
+ return newTableSize;
+
+ if (isPowerOf2(keyCount))
+ return keyCount * 4;
+
+ return nextPowerOf2(keyCount) * 2;
+}
+
+void Structure::materializePropertyMap()
+{
+ ASSERT(!m_propertyTable);
+
+ Vector<Structure*, 8> structures;
+ structures.append(this);
+
+ Structure* structure = this;
+
+ // Search for the last Structure with a property table.
+ while ((structure = structure->previousID())) {
+ if (structure->m_isPinnedPropertyTable) {
+ ASSERT(structure->m_propertyTable);
+ ASSERT(!structure->m_previous);
+
+ m_propertyTable = structure->copyPropertyTable();
+ break;
+ }
+
+ structures.append(structure);
+ }
+
+ if (!m_propertyTable)
+ createPropertyMapHashTable(sizeForKeyCount(m_offset + 1));
+ else {
+ if (sizeForKeyCount(m_offset + 1) > m_propertyTable->size)
+ rehashPropertyMapHashTable(sizeForKeyCount(m_offset + 1)); // This could be made more efficient by combining with the copy above.
+ }
+
+ for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
+ structure = structures[i];
+ structure->m_nameInPrevious->ref();
+ PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed);
+ insertIntoPropertyMapHashTable(entry);
+ }
+}
+
+void Structure::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject, unsigned listedAttributes)
+{
+ bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary) && (listedAttributes & Prototype);
+
+ if (shouldCache && m_cachedPropertyNameArrayData) {
+ if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
+ propertyNames.setData(m_cachedPropertyNameArrayData);
+ return;
+ }
+ clearEnumerationCache();
+ }
+ bool includeNonEnumerable = false;
+ if (listedAttributes & NonEnumerable)
+ includeNonEnumerable = true;
+ getNamesFromPropertyTable(propertyNames, includeNonEnumerable);
+ getNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames, includeNonEnumerable);
+
+ if ((listedAttributes & Prototype) && m_prototype.isObject()) {
+ propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly.
+ asObject(m_prototype)->getPropertyNames(exec, propertyNames);
+ }
+
+ if (shouldCache) {
+ StructureChain* protoChain = prototypeChain(exec);
+ m_cachedPropertyNameArrayData = propertyNames.data();
+ if (!protoChain->isCacheable())
+ return;
+ m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain);
+ m_cachedPropertyNameArrayData->setCachedStructure(this);
+ }
+}
+
+void Structure::clearEnumerationCache()
+{
+ if (m_cachedPropertyNameArrayData)
+ m_cachedPropertyNameArrayData->setCachedStructure(0);
+ m_cachedPropertyNameArrayData.clear();
+}
+
+void Structure::growPropertyStorageCapacity()
+{
+ if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
+ m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity;
+ else
+ m_propertyStorageCapacity *= 2;
+}
+
+void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
+{
+ const UString::Rep* rep = propertyName._ustring.rep();
+
+ materializePropertyMapIfNecessary();
+
+ ASSERT(m_isDictionary);
+ ASSERT(m_propertyTable);
+
+ unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+ ++numProbes;
+#endif
+
+ unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+ ASSERT(entryIndex != emptyEntryIndex);
+
+ if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+ m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+ return;
+ }
+
+#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];
+ ASSERT(entryIndex != emptyEntryIndex);
+
+ if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+ m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+ return;
+ }
+ }
+}
+
+PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+{
+ ASSERT(!structure->m_isDictionary);
+ ASSERT(structure->typeInfo().type() == ObjectType);
+
+ if (structure->m_usingSingleTransitionSlot) {
+ Structure* existingTransition = structure->m_transitions.singleTransition;
+ if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep()
+ && existingTransition->m_attributesInPrevious == attributes
+ && existingTransition->m_specificValueInPrevious == specificValue) {
+
+ ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset);
+ offset = structure->m_transitions.singleTransition->m_offset;
+ return existingTransition;
+ }
+ } else {
+ if (Structure* existingTransition = structure->m_transitions.table->get(make_pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> >(propertyName.ustring().rep(), make_pair(attributes, specificValue)))) {
+ ASSERT(existingTransition->m_offset != noOffset);
+ offset = existingTransition->m_offset;
+ return existingTransition;
+ }
+ }
+
+ return 0;
+}
+
+PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
+{
+ ASSERT(!structure->m_isDictionary);
+ ASSERT(structure->typeInfo().type() == ObjectType);
+ ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
+
+ if (structure->transitionCount() > s_maxTransitionLength) {
+ RefPtr<Structure> transition = toDictionaryTransition(structure);
+ ASSERT(structure != transition);
+ offset = transition->put(propertyName, attributes, specificValue);
+ if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
+ transition->growPropertyStorageCapacity();
+ return transition.release();
+ }
+
+ RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
+
+ transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
+ transition->m_previous = structure;
+ transition->m_nameInPrevious = propertyName.ustring().rep();
+ transition->m_attributesInPrevious = attributes;
+ transition->m_specificValueInPrevious = specificValue;
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ if (structure->m_propertyTable) {
+ if (structure->m_isPinnedPropertyTable)
+ transition->m_propertyTable = structure->copyPropertyTable();
+ else {
+ transition->m_propertyTable = structure->m_propertyTable;
+ structure->m_propertyTable = 0;
+ }
+ } else {
+ if (structure->m_previous)
+ transition->materializePropertyMap();
+ else
+ transition->createPropertyMapHashTable();
+ }
+
+ offset = transition->put(propertyName, attributes, specificValue);
+ if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
+ transition->growPropertyStorageCapacity();
+
+ transition->m_offset = offset;
+
+ if (structure->m_usingSingleTransitionSlot) {
+ if (!structure->m_transitions.singleTransition) {
+ structure->m_transitions.singleTransition = transition.get();
+ return transition.release();
+ }
+
+ Structure* existingTransition = structure->m_transitions.singleTransition;
+ structure->m_usingSingleTransitionSlot = false;
+ StructureTransitionTable* transitionTable = new StructureTransitionTable;
+ structure->m_transitions.table = transitionTable;
+ transitionTable->add(make_pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> >(existingTransition->m_nameInPrevious.get(), make_pair(existingTransition->m_attributesInPrevious, existingTransition->m_specificValueInPrevious)), existingTransition);
+ }
+ structure->m_transitions.table->add(make_pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> >(propertyName.ustring().rep(), make_pair(attributes, specificValue)), transition.get());
+ return transition.release();
+}
+
+PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset)
+{
+ ASSERT(!structure->m_isDictionary);
+
+ RefPtr<Structure> transition = toDictionaryTransition(structure);
+
+ offset = transition->remove(propertyName);
+
+ return transition.release();
+}
+
+PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValue prototype)
+{
+ RefPtr<Structure> transition = create(prototype, structure->typeInfo());
+
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ // Don't set m_offset, as one can not transition to this.
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
+
+ return transition.release();
+}
+
+PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction)
+{
+ RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
+
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ // Don't set m_offset, as one can not transition to this.
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
+
+ bool removed = transition->despecifyFunction(replaceFunction);
+ ASSERT_UNUSED(removed, removed);
+
+ return transition.release();
+}
+
+PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
+{
+ RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
+
+ // Don't set m_offset, as one can not transition to this.
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
+
+ return transition.release();
+}
+
+PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure)
+{
+ ASSERT(!structure->m_isDictionary);
+
+ RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
+ transition->m_isDictionary = true;
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
+
+ return transition.release();
+}
+
+PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
+{
+ ASSERT(structure->m_isDictionary);
+
+ // Since dictionary Structures are not shared, and no opcodes specialize
+ // for them, we don't need to allocate a new Structure when transitioning
+ // to non-dictionary status.
+
+ // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the
+ // deleted offsets vector) before transitioning from dictionary.
+ if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty())
+ structure->m_isDictionary = false;
+
+ return structure;
+}
+
+size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
+{
+ ASSERT(!m_transitions.singleTransition);
+
+ materializePropertyMapIfNecessary();
+
+ m_isPinnedPropertyTable = true;
+ size_t offset = put(propertyName, attributes, specificValue);
+ if (propertyStorageSize() > propertyStorageCapacity())
+ growPropertyStorageCapacity();
+ clearEnumerationCache();
+ return offset;
+}
+
+size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
+{
+ ASSERT(!m_transitions.singleTransition);
+ ASSERT(m_isDictionary);
+
+ materializePropertyMapIfNecessary();
+
+ m_isPinnedPropertyTable = true;
+ size_t offset = remove(propertyName);
+ clearEnumerationCache();
+ return offset;
+}
+
+#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 Structure::checkConsistency()
+{
+}
+
+#endif
+
+PropertyMapHashTable* Structure::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();
+ }
+
+ // Copy the deletedOffsets vector.
+ if (m_propertyTable->deletedOffsets)
+ newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets);
+
+ return newTable;
+}
+
+size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue)
+{
+ materializePropertyMapIfNecessary();
+ if (!m_propertyTable)
+ return notFound;
+
+ unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+ ++numProbes;
+#endif
+
+ unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+ if (entryIndex == emptyEntryIndex)
+ return notFound;
+
+ if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+ attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
+ specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue;
+ 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 notFound;
+
+ if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+ attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
+ specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue;
+ return m_propertyTable->entries()[entryIndex - 1].offset;
+ }
+ }
+}
+
+bool Structure::despecifyFunction(const Identifier& propertyName)
+{
+ ASSERT(!propertyName.isNull());
+
+ materializePropertyMapIfNecessary();
+ if (!m_propertyTable)
+ return false;
+
+ 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 false;
+
+ if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+ ASSERT(m_propertyTable->entries()[entryIndex - 1].specificValue);
+ m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+ return true;
+ }
+
+#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 false;
+
+ if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+ ASSERT(m_propertyTable->entries()[entryIndex - 1].specificValue);
+ m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+ return true;
+ }
+ }
+}
+
+size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
+{
+ ASSERT(!propertyName.isNull());
+ ASSERT(get(propertyName) == 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].specificValue = specificValue;
+ m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
+
+ unsigned newOffset;
+ if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) {
+ newOffset = m_propertyTable->deletedOffsets->last();
+ m_propertyTable->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 Structure::remove(const Identifier& propertyName)
+{
+ ASSERT(!propertyName.isNull());
+
+ checkConsistency();
+
+ UString::Rep* rep = propertyName._ustring.rep();
+
+ if (!m_propertyTable)
+ return 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 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].specificValue = 0;
+ m_propertyTable->entries()[entryIndex - 1].offset = 0;
+
+ if (!m_propertyTable->deletedOffsets)
+ m_propertyTable->deletedOffsets = new Vector<unsigned>;
+ m_propertyTable->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 Structure::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 Structure::createPropertyMapHashTable()
+{
+ ASSERT(sizeForKeyCount(7) == newTableSize);
+ createPropertyMapHashTable(newTableSize);
+}
+
+void Structure::createPropertyMapHashTable(unsigned newTableSize)
+{
+ ASSERT(!m_propertyTable);
+ ASSERT(isPowerOf2(newTableSize));
+
+ checkConsistency();
+
+ m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize)));
+ m_propertyTable->size = newTableSize;
+ m_propertyTable->sizeMask = newTableSize - 1;
+
+ checkConsistency();
+}
+
+void Structure::expandPropertyMapHashTable()
+{
+ ASSERT(m_propertyTable);
+ rehashPropertyMapHashTable(m_propertyTable->size * 2);
+}
+
+void Structure::rehashPropertyMapHashTable()
+{
+ ASSERT(m_propertyTable);
+ ASSERT(m_propertyTable->size);
+ rehashPropertyMapHashTable(m_propertyTable->size);
+}
+
+void Structure::rehashPropertyMapHashTable(unsigned newTableSize)
+{
+ ASSERT(m_propertyTable);
+ ASSERT(isPowerOf2(newTableSize));
+
+ 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;
+ m_propertyTable->deletedOffsets = oldTable->deletedOffsets;
+
+ 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 Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool includeNonEnumerable)
+{
+ materializePropertyMapIfNecessary();
+ 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
+ && (includeNonEnumerable || !(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
+ && (includeNonEnumerable || !(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);
+ }
+}
+
+void Structure::getNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+{
+ // Add properties from the static hashtables of properties
+ for (; classInfo; classInfo = classInfo->parentClass) {
+ const HashTable* table = classInfo->propHashTable(exec);
+ if (!table)
+ continue;
+ table->initializeIfNeeded(exec);
+ ASSERT(table->table);
+
+ int hashSizeMask = table->compactSize - 1;
+ const HashEntry* entry = table->table;
+ for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
+ if (entry->key() && (includeNonEnumerable || !(entry->attributes() & DontEnum)))
+ propertyNames.add(entry->key());
+ }
+ }
+}
+
+#if DO_PROPERTYMAP_CONSTENCY_CHECK
+
+void Structure::checkConsistency()
+{
+ if (!m_propertyTable)
+ return;
+
+ ASSERT(m_propertyTable->size >= newTableSize);
+ 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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h
new file mode 100644
index 0000000..ca4552b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h
@@ -0,0 +1,242 @@
+/*
+ * 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 Structure_h
+#define Structure_h
+
+#include "Identifier.h"
+#include "JSType.h"
+#include "JSValue.h"
+#include "PropertyMapHashTable.h"
+#include "StructureTransitionTable.h"
+#include "JSTypeInfo.h"
+#include "UString.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 StructureChain;
+
+ class Structure : public RefCounted<Structure> {
+ public:
+ enum ListedAttribute {
+ NonEnumerable = 1 << 1,
+ Prototype = 1 << 2
+ };
+
+ friend class JIT;
+ static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo)
+ {
+ return adoptRef(new Structure(prototype, typeInfo));
+ }
+
+ static void startIgnoringLeaks();
+ static void stopIgnoringLeaks();
+
+ static void dumpStatistics();
+
+ static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+ static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset);
+ static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype);
+ static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&);
+ static PassRefPtr<Structure> getterSetterTransition(Structure*);
+ static PassRefPtr<Structure> toDictionaryTransition(Structure*);
+ static PassRefPtr<Structure> fromDictionaryTransition(Structure*);
+
+ ~Structure();
+
+ void mark()
+ {
+ if (!m_prototype.marked())
+ m_prototype.mark();
+ }
+
+ // These should be used with caution.
+ size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
+ size_t removePropertyWithoutTransition(const Identifier& propertyName);
+ void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; }
+
+ bool isDictionary() const { return m_isDictionary; }
+
+ const TypeInfo& typeInfo() const { return m_typeInfo; }
+
+ JSValue storedPrototype() const { return m_prototype; }
+ JSValue prototypeForLookup(ExecState*) const;
+ StructureChain* prototypeChain(ExecState*) const;
+
+ Structure* previousID() const { return m_previous.get(); }
+
+ void growPropertyStorageCapacity();
+ size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
+ size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
+ bool isUsingInlineStorage() const;
+
+ size_t get(const Identifier& propertyName);
+ size_t get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue);
+ size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
+ {
+ ASSERT(!propertyName.isNull());
+ return get(propertyName._ustring.rep(), attributes, specificValue);
+ }
+
+ void getPropertyNames(ExecState*, PropertyNameArray&, JSObject*, unsigned listedAttributes = Prototype);
+
+ bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
+ void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
+
+ bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
+
+ JSCell* specificValue() { return m_specificValueInPrevious; }
+ void despecifyDictionaryFunction(const Identifier& propertyName);
+
+ private:
+ Structure(JSValue prototype, const TypeInfo&);
+
+ size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
+ size_t remove(const Identifier& propertyName);
+ void getNamesFromPropertyTable(PropertyNameArray&, bool includeNonEnumerable = false);
+ void getNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&, bool includeNonEnumerable = false);
+
+ void expandPropertyMapHashTable();
+ void rehashPropertyMapHashTable();
+ void rehashPropertyMapHashTable(unsigned newTableSize);
+ void createPropertyMapHashTable();
+ void createPropertyMapHashTable(unsigned newTableSize);
+ void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
+ void checkConsistency();
+
+ bool despecifyFunction(const Identifier&);
+
+ PropertyMapHashTable* copyPropertyTable();
+ void materializePropertyMap();
+ void materializePropertyMapIfNecessary()
+ {
+ if (m_propertyTable || !m_previous)
+ return;
+ materializePropertyMap();
+ }
+
+ void clearEnumerationCache();
+
+ signed char transitionCount() const
+ {
+ // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
+ return m_offset == noOffset ? 0 : m_offset + 1;
+ }
+
+ bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
+
+ static const unsigned emptyEntryIndex = 0;
+
+ static const signed char s_maxTransitionLength = 64;
+
+ static const signed char noOffset = -1;
+
+ TypeInfo m_typeInfo;
+
+ JSValue m_prototype;
+ mutable RefPtr<StructureChain> m_cachedPrototypeChain;
+
+ RefPtr<Structure> m_previous;
+ RefPtr<UString::Rep> m_nameInPrevious;
+
+ union {
+ Structure* singleTransition;
+ StructureTransitionTable* table;
+ } m_transitions;
+ JSCell* m_specificValueInPrevious;
+
+ RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
+
+ PropertyMapHashTable* m_propertyTable;
+
+ size_t m_propertyStorageCapacity;
+ signed char m_offset;
+
+ bool m_isDictionary : 1;
+ bool m_isPinnedPropertyTable : 1;
+ bool m_hasGetterSetterProperties : 1;
+ bool m_usingSingleTransitionSlot : 1;
+ unsigned m_attributesInPrevious : 7;
+ };
+
+ inline size_t Structure::get(const Identifier& propertyName)
+ {
+ ASSERT(!propertyName.isNull());
+
+ materializePropertyMapIfNecessary();
+ 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 // Structure_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp
new file mode 100644
index 0000000..acebc86
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp
@@ -0,0 +1,66 @@
+/*
+ * 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 "StructureChain.h"
+#include "Structure.h"
+
+#include "JSObject.h"
+#include "Structure.h"
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+StructureChain::StructureChain(Structure* head)
+{
+ size_t size = 0;
+ for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
+ ++size;
+
+ m_vector.set(new RefPtr<Structure>[size + 1]);
+
+ size_t i = 0;
+ for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
+ m_vector[i++] = current;
+ m_vector[i] = 0;
+}
+
+PassRefPtr<StructureChain> StructureChain::create(Structure* head)
+{
+ return adoptRef(new StructureChain(head));
+}
+
+bool StructureChain::isCacheable() const
+{
+ uint32_t i = 0;
+
+ while (m_vector[i]) {
+ if (m_vector[i++]->isDictionary())
+ return false;
+ }
+ return true;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h
new file mode 100644
index 0000000..5990e17
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h
@@ -0,0 +1,52 @@
+/*
+ * 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 StructureChain_h
+#define StructureChain_h
+
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+ class Structure;
+
+ class StructureChain : public RefCounted<StructureChain> {
+ public:
+ static PassRefPtr<StructureChain> create(Structure* head);
+ RefPtr<Structure>* head() { return m_vector.get(); }
+ bool isCacheable() const;
+
+ private:
+ StructureChain(Structure* head);
+
+ OwnArrayPtr<RefPtr<Structure> > m_vector;
+ };
+
+} // namespace JSC
+
+#endif // StructureChain_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h
new file mode 100644
index 0000000..804cbeb
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -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.
+ */
+
+#ifndef StructureTransitionTable_h
+#define StructureTransitionTable_h
+
+#include "UString.h"
+#include <wtf/HashFunctions.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashTraits.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+ class Structure;
+
+ struct StructureTransitionTableHash {
+ typedef std::pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> > 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 StructureTransitionTableHashTraits {
+ typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
+ typedef WTF::GenericHashTraits<unsigned> SecondFirstTraits;
+ typedef WTF::GenericHashTraits<JSCell*> SecondSecondTraits;
+ typedef std::pair<FirstTraits::TraitType, std::pair<SecondFirstTraits::TraitType, SecondSecondTraits::TraitType> > TraitType;
+
+ static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondFirstTraits::emptyValueIsZero && SecondSecondTraits::emptyValueIsZero;
+ static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), std::make_pair(SecondFirstTraits::emptyValue(), SecondSecondTraits::emptyValue())); }
+
+ static const bool needsDestruction = FirstTraits::needsDestruction || SecondFirstTraits::needsDestruction || SecondSecondTraits::needsDestruction;
+
+ static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
+ static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
+ };
+
+ typedef HashMap<StructureTransitionTableHash::Key, Structure*, StructureTransitionTableHash, StructureTransitionTableHashTraits> StructureTransitionTable;
+
+} // namespace JSC
+
+#endif // StructureTransitionTable_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SymbolTable.h
new file mode 100644
index 0000000..c00f95a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp
new file mode 100644
index 0000000..045a33a
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TimeoutChecker.h"
+
+#include "CallFrame.h"
+#include "JSGlobalObject.h"
+
+#if PLATFORM(DARWIN)
+#include <mach/mach.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if PLATFORM(WIN_OS)
+#include <windows.h>
+#endif
+
+#if PLATFORM(QT)
+#include <QDateTime>
+#endif
+
+using namespace std;
+
+namespace JSC {
+
+// Number of ticks before the first timeout check is done.
+static const int ticksUntilFirstCheck = 1024;
+
+// Default number of milliseconds between each timeout check.
+static const int defaultIntervalBetweenChecks = 1000;
+
+// Returns the time the current thread has spent executing, in milliseconds.
+static inline unsigned getCPUTime()
+{
+#if PLATFORM(DARWIN)
+ mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
+ thread_basic_info_data_t info;
+
+ // Get thread information
+ mach_port_t threadPort = mach_thread_self();
+ thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
+ mach_port_deallocate(mach_task_self(), threadPort);
+
+ unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
+ time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
+
+ return time;
+#elif HAVE(SYS_TIME_H)
+ // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag.
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#elif PLATFORM(QT)
+ QDateTime t = QDateTime::currentDateTime();
+ return t.toTime_t() * 1000 + t.time().msec();
+#elif PLATFORM(WIN_OS)
+ union {
+ FILETIME fileTime;
+ unsigned long long fileTimeAsLong;
+ } userTime, kernelTime;
+
+ // GetThreadTimes won't accept NULL arguments so we pass these even though
+ // they're not used.
+ FILETIME creationTime, exitTime;
+
+ GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
+
+ return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
+#else
+#error Platform does not have getCurrentTime function
+#endif
+}
+
+TimeoutChecker::TimeoutChecker()
+ : m_timeoutInterval(0)
+ , m_startCount(0)
+ , m_intervalBetweenChecks(defaultIntervalBetweenChecks)
+{
+ reset();
+}
+
+TimeoutChecker::~TimeoutChecker()
+{
+}
+
+void TimeoutChecker::reset()
+{
+ m_ticksUntilNextCheck = ticksUntilFirstCheck;
+ m_timeAtLastCheck = 0;
+ m_timeExecuting = 0;
+}
+
+bool TimeoutChecker::didTimeOut(ExecState* exec)
+{
+ unsigned currentTime = getCPUTime();
+
+ if (!m_timeAtLastCheck) {
+ // Suspicious amount of looping in a script -- start timing it
+ m_timeAtLastCheck = currentTime;
+ return false;
+ }
+
+ unsigned timeDiff = currentTime - m_timeAtLastCheck;
+
+ if (timeDiff == 0)
+ timeDiff = 1;
+
+ m_timeExecuting += timeDiff;
+ m_timeAtLastCheck = currentTime;
+
+ // Adjust the tick threshold so we get the next checkTimeout call in the
+ // interval specified in intervalBetweenChecks.
+ m_ticksUntilNextCheck = static_cast<unsigned>((static_cast<float>(m_intervalBetweenChecks) / timeDiff) * m_ticksUntilNextCheck);
+ // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
+ // preferred script check time interval.
+ if (m_ticksUntilNextCheck == 0)
+ m_ticksUntilNextCheck = ticksUntilFirstCheck;
+
+ if (m_timeoutInterval && m_timeExecuting > m_timeoutInterval) {
+ if (exec->dynamicGlobalObject()->shouldInterruptScript())
+ return true;
+
+ reset();
+ }
+
+ return false;
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h
new file mode 100644
index 0000000..1680d6d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.h
@@ -0,0 +1,76 @@
+/*
+ * 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 TimeoutChecker_h
+#define TimeoutChecker_h
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ class ExecState;
+
+ class TimeoutChecker {
+ public:
+ TimeoutChecker();
+ virtual ~TimeoutChecker();
+
+ void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; }
+ void setCheckInterval(unsigned checkInterval) { if (checkInterval) m_intervalBetweenChecks = checkInterval; }
+
+ unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; }
+
+ void start()
+ {
+ if (!m_startCount)
+ reset();
+ ++m_startCount;
+ }
+
+ void stop()
+ {
+ ASSERT(m_startCount);
+ --m_startCount;
+ }
+
+ void reset();
+
+ virtual bool didTimeOut(ExecState*);
+
+ private:
+ unsigned m_timeoutInterval;
+ unsigned m_timeAtLastCheck;
+ unsigned m_timeExecuting;
+ unsigned m_startCount;
+ unsigned m_ticksUntilNextCheck;
+ unsigned m_intervalBetweenChecks;
+ };
+
+} // namespace JSC
+
+#endif // TimeoutChecker_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.d b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.d
new file mode 100644
index 0000000..b9efaff
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h
new file mode 100644
index 0000000..e544f66
--- /dev/null
+++ b/src/3rdparty/javascriptcore/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
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp
new file mode 100644
index 0000000..fa19932
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp
@@ -0,0 +1,1781 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * Copyright (C) 2009 Google 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 "UString.h"
+
+#include "JSGlobalObjectFunctions.h"
+#include "Collector.h"
+#include "dtoa.h"
+#include "Identifier.h"
+#include "Operations.h"
+#include <ctype.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/Vector.h>
+#include <wtf/unicode/UTF8.h>
+#include <wtf/StringExtras.h>
+
+#if HAVE(STRING_H)
+#include <string.h>
+#endif
+#if HAVE(STRINGS_H)
+#include <strings.h>
+#endif
+
+using namespace WTF;
+using namespace WTF::Unicode;
+using namespace std;
+
+// This can be tuned differently per platform by putting platform #ifs right here.
+// If you don't define this macro at all, then copyChars will just call directly
+// to memcpy.
+#define USTRING_COPY_CHARS_INLINE_CUTOFF 20
+
+namespace JSC {
+
+extern const double NaN;
+extern const double Inf;
+
+// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
+static const int minLengthToShare = 10;
+
+static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); }
+static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); }
+
+static inline UChar* allocChars(size_t length)
+{
+ ASSERT(length);
+ if (length > maxUChars())
+ return 0;
+ return static_cast<UChar*>(tryFastMalloc(sizeof(UChar) * length));
+}
+
+static inline UChar* reallocChars(UChar* buffer, size_t length)
+{
+ ASSERT(length);
+ if (length > maxUChars())
+ return 0;
+ return static_cast<UChar*>(tryFastRealloc(buffer, sizeof(UChar) * length));
+}
+
+static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
+{
+#ifdef USTRING_COPY_CHARS_INLINE_CUTOFF
+ if (numCharacters <= USTRING_COPY_CHARS_INLINE_CUTOFF) {
+ for (unsigned i = 0; i < numCharacters; ++i)
+ destination[i] = source[i];
+ return;
+ }
+#endif
+ memcpy(destination, source, numCharacters * sizeof(UChar));
+}
+
+COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes);
+
+CString::CString(const char* c)
+ : m_length(strlen(c))
+ , m_data(new char[m_length + 1])
+{
+ memcpy(m_data, c, m_length + 1);
+}
+
+CString::CString(const char* c, size_t length)
+ : m_length(length)
+ , m_data(new char[length + 1])
+{
+ memcpy(m_data, c, m_length);
+ m_data[m_length] = 0;
+}
+
+CString::CString(const CString& b)
+{
+ m_length = b.m_length;
+ if (b.m_data) {
+ m_data = new char[m_length + 1];
+ memcpy(m_data, b.m_data, m_length + 1);
+ } else
+ m_data = 0;
+}
+
+CString::~CString()
+{
+ delete [] m_data;
+}
+
+CString CString::adopt(char* c, size_t length)
+{
+ CString s;
+ s.m_data = c;
+ s.m_length = length;
+ return s;
+}
+
+CString& CString::append(const CString& t)
+{
+ char* n;
+ n = new char[m_length + t.m_length + 1];
+ if (m_length)
+ memcpy(n, m_data, m_length);
+ if (t.m_length)
+ memcpy(n + m_length, t.m_data, t.m_length);
+ m_length += t.m_length;
+ n[m_length] = 0;
+
+ delete [] m_data;
+ m_data = n;
+
+ return *this;
+}
+
+CString& CString::operator=(const char* c)
+{
+ if (m_data)
+ delete [] m_data;
+ m_length = strlen(c);
+ m_data = new char[m_length + 1];
+ memcpy(m_data, c, m_length + 1);
+
+ return *this;
+}
+
+CString& CString::operator=(const CString& str)
+{
+ if (this == &str)
+ return *this;
+
+ if (m_data)
+ delete [] m_data;
+ m_length = str.m_length;
+ if (str.m_data) {
+ m_data = new char[m_length + 1];
+ memcpy(m_data, str.m_data, m_length + 1);
+ } else
+ m_data = 0;
+
+ return *this;
+}
+
+bool operator==(const CString& c1, const CString& c2)
+{
+ size_t len = c1.size();
+ return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);
+}
+
+// These static strings are immutable, except for rc, whose initial value is chosen to
+// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
+static UChar sharedEmptyChar;
+UString::BaseString* UString::Rep::nullBaseString;
+UString::BaseString* UString::Rep::emptyBaseString;
+UString* UString::nullUString;
+
+static void initializeStaticBaseString(UString::BaseString& base)
+{
+ base.rc = INT_MAX / 2;
+ base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
+ base.checkConsistency();
+}
+
+void initializeUString()
+{
+ UString::Rep::nullBaseString = new UString::BaseString(0, 0);
+ initializeStaticBaseString(*UString::Rep::nullBaseString);
+
+ UString::Rep::emptyBaseString = new UString::BaseString(&sharedEmptyChar, 0);
+ initializeStaticBaseString(*UString::Rep::emptyBaseString);
+
+ UString::nullUString = new UString;
+}
+
+static char* statBuffer = 0; // Only used for debugging via UString::ascii().
+
+PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l)
+{
+ UChar* copyD = static_cast<UChar*>(fastMalloc(l * sizeof(UChar)));
+ copyChars(copyD, d, l);
+ return create(copyD, l);
+}
+
+PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
+{
+ if (!string)
+ return &UString::Rep::null();
+
+ size_t length = strlen(string);
+ Vector<UChar, 1024> buffer(length);
+ UChar* p = buffer.data();
+ if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
+ return &UString::Rep::null();
+
+ return UString::Rep::createCopying(buffer.data(), p - buffer.data());
+}
+
+PassRefPtr<UString::Rep> UString::Rep::create(UChar* string, int length, PassRefPtr<UString::SharedUChar> sharedBuffer)
+{
+ PassRefPtr<UString::Rep> rep = create(string, length);
+ rep->baseString()->setSharedBuffer(sharedBuffer);
+ rep->checkConsistency();
+ return rep;
+}
+
+UString::SharedUChar* UString::Rep::sharedBuffer()
+{
+ UString::BaseString* base = baseString();
+ if (len < minLengthToShare)
+ return 0;
+
+ return base->sharedBuffer();
+}
+
+void UString::Rep::destroy()
+{
+ checkConsistency();
+
+ // Static null and empty strings can never be destroyed, but we cannot rely on
+ // reference counting, because ref/deref are not thread-safe.
+ if (!isStatic()) {
+ if (identifierTable())
+ Identifier::remove(this);
+
+ UString::BaseString* base = baseString();
+ if (base == this) {
+ if (m_sharedBuffer)
+ m_sharedBuffer->deref();
+ else
+ fastFree(base->buf);
+ } else
+ base->deref();
+
+ delete this;
+ }
+}
+
+// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+// or anything like that.
+const unsigned PHI = 0x9e3779b9U;
+
+// Paul Hsieh's SuperFastHash
+// http://www.azillionmonkeys.com/qed/hash.html
+unsigned UString::Rep::computeHash(const UChar* s, int len)
+{
+ unsigned l = len;
+ uint32_t hash = PHI;
+ uint32_t tmp;
+
+ int rem = l & 1;
+ l >>= 1;
+
+ // Main loop
+ for (; l > 0; l--) {
+ hash += s[0];
+ tmp = (s[1] << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ s += 2;
+ hash += hash >> 11;
+ }
+
+ // Handle end case
+ if (rem) {
+ hash += s[0];
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ }
+
+ // Force "avalanching" of final 127 bits
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 2;
+ hash += hash >> 15;
+ hash ^= hash << 10;
+
+ // this avoids ever returning a hash code of 0, since that is used to
+ // signal "hash not computed yet", using a value that is likely to be
+ // effectively the same as 0 when the low bits are masked
+ if (hash == 0)
+ hash = 0x80000000;
+
+ return hash;
+}
+
+// Paul Hsieh's SuperFastHash
+// http://www.azillionmonkeys.com/qed/hash.html
+unsigned UString::Rep::computeHash(const char* s, int l)
+{
+ // This hash is designed to work on 16-bit chunks at a time. But since the normal case
+ // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
+ // were 16-bit chunks, which should give matching results
+
+ uint32_t hash = PHI;
+ uint32_t tmp;
+
+ size_t rem = l & 1;
+ l >>= 1;
+
+ // Main loop
+ for (; l > 0; l--) {
+ hash += static_cast<unsigned char>(s[0]);
+ tmp = (static_cast<unsigned char>(s[1]) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ s += 2;
+ hash += hash >> 11;
+ }
+
+ // Handle end case
+ if (rem) {
+ hash += static_cast<unsigned char>(s[0]);
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ }
+
+ // Force "avalanching" of final 127 bits
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 2;
+ hash += hash >> 15;
+ hash ^= hash << 10;
+
+ // this avoids ever returning a hash code of 0, since that is used to
+ // signal "hash not computed yet", using a value that is likely to be
+ // effectively the same as 0 when the low bits are masked
+ if (hash == 0)
+ hash = 0x80000000;
+
+ return hash;
+}
+
+#ifndef NDEBUG
+void UString::Rep::checkConsistency() const
+{
+ const UString::BaseString* base = baseString();
+
+ // There is no recursion for base strings.
+ ASSERT(base == base->baseString());
+
+ if (isStatic()) {
+ // There are only two static strings: null and empty.
+ ASSERT(!len);
+
+ // Static strings cannot get in identifier tables, because they are globally shared.
+ ASSERT(!identifierTable());
+ }
+
+ // The string fits in buffer.
+ ASSERT(base->usedPreCapacity <= base->preCapacity);
+ ASSERT(base->usedCapacity <= base->capacity);
+ ASSERT(-offset <= base->usedPreCapacity);
+ ASSERT(offset + len <= base->usedCapacity);
+}
+#endif
+
+UString::SharedUChar* UString::BaseString::sharedBuffer()
+{
+ if (!m_sharedBuffer)
+ setSharedBuffer(SharedUChar::create(new OwnFastMallocPtr<UChar>(buf)));
+ return m_sharedBuffer;
+}
+
+void UString::BaseString::setSharedBuffer(PassRefPtr<UString::SharedUChar> sharedBuffer)
+{
+ // The manual steps below are because m_sharedBuffer can't be a RefPtr. m_sharedBuffer
+ // is in a union with another variable to avoid making BaseString any larger.
+ if (m_sharedBuffer)
+ m_sharedBuffer->deref();
+ m_sharedBuffer = sharedBuffer.releaseRef();
+}
+
+bool UString::BaseString::slowIsBufferReadOnly()
+{
+ // The buffer may not be modified as soon as the underlying data has been shared with another class.
+ if (m_sharedBuffer->isShared())
+ return true;
+
+ // At this point, we know it that the underlying buffer isn't shared outside of this base class,
+ // so get rid of m_sharedBuffer.
+ OwnPtr<OwnFastMallocPtr<UChar> > mallocPtr(m_sharedBuffer->release());
+ UChar* unsharedBuf = const_cast<UChar*>(mallocPtr->release());
+ setSharedBuffer(0);
+ preCapacity += (buf - unsharedBuf);
+ buf = unsharedBuf;
+ return false;
+}
+
+// Put these early so they can be inlined.
+static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize)
+{
+ // Combine capacitySize & precapacitySize to produce a single size to allocate,
+ // check that doing so does not result in overflow.
+ size_t size = capacitySize + precapacitySize;
+ if (size < capacitySize)
+ return overflowIndicator();
+
+ // Small Strings (up to 4 pages):
+ // Expand the allocation size to 112.5% of the amount requested. This is largely sicking
+ // to our previous policy, however 112.5% is cheaper to calculate.
+ if (size < 0x4000) {
+ size_t expandedSize = ((size + (size >> 3)) | 15) + 1;
+ // Given the limited range within which we calculate the expansion in this
+ // fashion the above calculation should never overflow.
+ ASSERT(expandedSize >= size);
+ ASSERT(expandedSize < maxUChars());
+ return expandedSize;
+ }
+
+ // Medium Strings (up to 128 pages):
+ // For pages covering multiple pages over-allocation is less of a concern - any unused
+ // space will not be paged in if it is not used, so this is purely a VM overhead. For
+ // these strings allocate 2x the requested size.
+ if (size < 0x80000) {
+ size_t expandedSize = ((size + size) | 0xfff) + 1;
+ // Given the limited range within which we calculate the expansion in this
+ // fashion the above calculation should never overflow.
+ ASSERT(expandedSize >= size);
+ ASSERT(expandedSize < maxUChars());
+ return expandedSize;
+ }
+
+ // Large Strings (to infinity and beyond!):
+ // Revert to our 112.5% policy - probably best to limit the amount of unused VM we allow
+ // any individual string be responsible for.
+ size_t expandedSize = ((size + (size >> 3)) | 0xfff) + 1;
+
+ // Check for overflow - any result that is at least as large as requested (but
+ // still below the limit) is okay.
+ if ((expandedSize >= size) && (expandedSize < maxUChars()))
+ return expandedSize;
+ return overflowIndicator();
+}
+
+static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
+{
+ rep->checkConsistency();
+ ASSERT(!rep->baseString()->isBufferReadOnly());
+
+ UString::BaseString* base = rep->baseString();
+
+ if (requiredLength > base->capacity) {
+ size_t newCapacity = expandedSize(requiredLength, base->preCapacity);
+ UChar* oldBuf = base->buf;
+ base->buf = reallocChars(base->buf, newCapacity);
+ if (!base->buf) {
+ base->buf = oldBuf;
+ return false;
+ }
+ base->capacity = newCapacity - base->preCapacity;
+ }
+ if (requiredLength > base->usedCapacity)
+ base->usedCapacity = requiredLength;
+
+ rep->checkConsistency();
+ return true;
+}
+
+bool UString::Rep::reserveCapacity(int capacity)
+{
+ // If this is an empty string there is no point 'growing' it - just allocate a new one.
+ // If the BaseString is shared with another string that is using more capacity than this
+ // string is, then growing the buffer won't help.
+ // If the BaseString's buffer is readonly, then it isn't allowed to grow.
+ UString::BaseString* base = baseString();
+ if (!base->buf || !base->capacity || (offset + len) != base->usedCapacity || base->isBufferReadOnly())
+ return false;
+
+ // If there is already sufficient capacity, no need to grow!
+ if (capacity <= base->capacity)
+ return true;
+
+ checkConsistency();
+
+ size_t newCapacity = expandedSize(capacity, base->preCapacity);
+ UChar* oldBuf = base->buf;
+ base->buf = reallocChars(base->buf, newCapacity);
+ if (!base->buf) {
+ base->buf = oldBuf;
+ return false;
+ }
+ base->capacity = newCapacity - base->preCapacity;
+
+ checkConsistency();
+ return true;
+}
+
+void UString::expandCapacity(int requiredLength)
+{
+ if (!JSC::expandCapacity(m_rep.get(), requiredLength))
+ makeNull();
+}
+
+void UString::expandPreCapacity(int requiredPreCap)
+{
+ m_rep->checkConsistency();
+ ASSERT(!m_rep->baseString()->isBufferReadOnly());
+
+ BaseString* base = m_rep->baseString();
+
+ if (requiredPreCap > base->preCapacity) {
+ size_t newCapacity = expandedSize(requiredPreCap, base->capacity);
+ int delta = newCapacity - base->capacity - base->preCapacity;
+
+ UChar* newBuf = allocChars(newCapacity);
+ if (!newBuf) {
+ makeNull();
+ return;
+ }
+ copyChars(newBuf + delta, base->buf, base->capacity + base->preCapacity);
+ fastFree(base->buf);
+ base->buf = newBuf;
+
+ base->preCapacity = newCapacity - base->capacity;
+ }
+ if (requiredPreCap > base->usedPreCapacity)
+ base->usedPreCapacity = requiredPreCap;
+
+ m_rep->checkConsistency();
+}
+
+static PassRefPtr<UString::Rep> createRep(const char* c)
+{
+ if (!c)
+ return &UString::Rep::null();
+
+ if (!c[0])
+ return &UString::Rep::empty();
+
+ size_t length = strlen(c);
+ UChar* d = allocChars(length);
+ if (!d)
+ return &UString::Rep::null();
+ else {
+ for (size_t i = 0; i < length; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ return UString::Rep::create(d, static_cast<int>(length));
+ }
+
+}
+
+UString::UString(const char* c)
+ : m_rep(createRep(c))
+{
+}
+
+UString::UString(const UChar* c, int length)
+{
+ if (length == 0)
+ m_rep = &Rep::empty();
+ else
+ m_rep = Rep::createCopying(c, length);
+}
+
+UString::UString(UChar* c, int length, bool copy)
+{
+ if (length == 0)
+ m_rep = &Rep::empty();
+ else if (copy)
+ m_rep = Rep::createCopying(c, length);
+ else
+ m_rep = Rep::create(c, length);
+}
+
+UString::UString(const Vector<UChar>& buffer)
+{
+ if (!buffer.size())
+ m_rep = &Rep::empty();
+ else
+ m_rep = Rep::createCopying(buffer.data(), buffer.size());
+}
+
+static ALWAYS_INLINE int newCapacityWithOverflowCheck(const int currentCapacity, const int extendLength, const bool plusOne = false)
+{
+ ASSERT_WITH_MESSAGE(extendLength >= 0, "extendedLength = %d", extendLength);
+
+ const int plusLength = plusOne ? 1 : 0;
+ if (currentCapacity > std::numeric_limits<int>::max() - extendLength - plusLength)
+ CRASH();
+
+ return currentCapacity + extendLength + plusLength;
+}
+
+static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const UChar* tData, int tSize)
+{
+ RefPtr<UString::Rep> rep = r;
+
+ rep->checkConsistency();
+
+ int thisSize = rep->size();
+ int thisOffset = rep->offset;
+ int length = thisSize + tSize;
+ UString::BaseString* base = rep->baseString();
+
+ // possible cases:
+ if (tSize == 0) {
+ // t is empty
+ } else if (thisSize == 0) {
+ // this is empty
+ rep = UString::Rep::createCopying(tData, tSize);
+ } else if (rep == base && !base->isShared()) {
+ // this is direct and has refcount of 1 (so we can just alter it directly)
+ if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
+ rep = &UString::Rep::null();
+ if (rep->data()) {
+ copyChars(rep->data() + thisSize, tData, tSize);
+ rep->len = length;
+ rep->_hash = 0;
+ }
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
+ // this reaches the end of the buffer - extend it if it's long enough to append to
+ if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
+ rep = &UString::Rep::null();
+ if (rep->data()) {
+ copyChars(rep->data() + thisSize, tData, tSize);
+ rep = UString::Rep::create(rep, 0, length);
+ }
+ } else {
+ // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
+ size_t newCapacity = expandedSize(length, 0);
+ UChar* d = allocChars(newCapacity);
+ if (!d)
+ rep = &UString::Rep::null();
+ else {
+ copyChars(d, rep->data(), thisSize);
+ copyChars(d + thisSize, tData, tSize);
+ rep = UString::Rep::create(d, length);
+ rep->baseString()->capacity = newCapacity;
+ }
+ }
+
+ rep->checkConsistency();
+
+ return rep.release();
+}
+
+static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const char* t)
+{
+ RefPtr<UString::Rep> rep = r;
+
+ rep->checkConsistency();
+
+ int thisSize = rep->size();
+ int thisOffset = rep->offset;
+ int tSize = static_cast<int>(strlen(t));
+ int length = thisSize + tSize;
+ UString::BaseString* base = rep->baseString();
+
+ // possible cases:
+ if (thisSize == 0) {
+ // this is empty
+ rep = createRep(t);
+ } else if (tSize == 0) {
+ // t is empty, we'll just return *this below.
+ } else if (rep == base && !base->isShared()) {
+ // this is direct and has refcount of 1 (so we can just alter it directly)
+ expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
+ UChar* d = rep->data();
+ if (d) {
+ for (int i = 0; i < tSize; ++i)
+ d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
+ rep->len = length;
+ rep->_hash = 0;
+ }
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
+ // this string reaches the end of the buffer - extend it
+ expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
+ UChar* d = rep->data();
+ if (d) {
+ for (int i = 0; i < tSize; ++i)
+ d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
+ rep = UString::Rep::create(rep, 0, length);
+ }
+ } else {
+ // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
+ size_t newCapacity = expandedSize(length, 0);
+ UChar* d = allocChars(newCapacity);
+ if (!d)
+ rep = &UString::Rep::null();
+ else {
+ copyChars(d, rep->data(), thisSize);
+ for (int i = 0; i < tSize; ++i)
+ d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
+ rep = UString::Rep::create(d, length);
+ rep->baseString()->capacity = newCapacity;
+ }
+ }
+
+ rep->checkConsistency();
+
+ return rep.release();
+}
+
+PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
+{
+ a->checkConsistency();
+ b->checkConsistency();
+
+ int aSize = a->size();
+ int bSize = b->size();
+ int aOffset = a->offset;
+
+ // possible cases:
+
+ UString::BaseString* aBase = a->baseString();
+ if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + aSize < aBase->capacity && !aBase->isBufferReadOnly()) {
+ // b is a single character (common fast case)
+ ++aBase->usedCapacity;
+ a->data()[aSize] = b->data()[0];
+ return UString::Rep::create(a, 0, aSize + 1);
+ }
+
+ // a is empty
+ if (aSize == 0)
+ return b;
+ // b is empty
+ if (bSize == 0)
+ return a;
+
+ int bOffset = b->offset;
+ int length = aSize + bSize;
+
+ UString::BaseString* bBase = b->baseString();
+ if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize
+ && (-bOffset != bBase->usedPreCapacity || aSize >= bSize) && !aBase->isBufferReadOnly()) {
+ // - a reaches the end of its buffer so it qualifies for shared append
+ // - also, it's at least a quarter the length of b - appending to a much shorter
+ // string does more harm than good
+ // - however, if b qualifies for prepend and is longer than a, we'd rather prepend
+
+ UString x(a);
+ x.expandCapacity(newCapacityWithOverflowCheck(aOffset, length));
+ if (!a->data() || !x.data())
+ return 0;
+ copyChars(a->data() + aSize, b->data(), bSize);
+ PassRefPtr<UString::Rep> result = UString::Rep::create(a, 0, length);
+
+ a->checkConsistency();
+ b->checkConsistency();
+ result->checkConsistency();
+
+ return result;
+ }
+
+ if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize && !bBase->isBufferReadOnly()) {
+ // - b reaches the beginning of its buffer so it qualifies for shared prepend
+ // - also, it's at least a quarter the length of a - prepending to a much shorter
+ // string does more harm than good
+ UString y(b);
+ y.expandPreCapacity(-bOffset + aSize);
+ if (!b->data() || !y.data())
+ return 0;
+ copyChars(b->data() - aSize, a->data(), aSize);
+ PassRefPtr<UString::Rep> result = UString::Rep::create(b, -aSize, length);
+
+ a->checkConsistency();
+ b->checkConsistency();
+ result->checkConsistency();
+
+ return result;
+ }
+
+ // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string
+ size_t newCapacity = expandedSize(length, 0);
+ UChar* d = allocChars(newCapacity);
+ if (!d)
+ return 0;
+ copyChars(d, a->data(), aSize);
+ copyChars(d + aSize, b->data(), bSize);
+ PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);
+ result->baseString()->capacity = newCapacity;
+
+ a->checkConsistency();
+ b->checkConsistency();
+ result->checkConsistency();
+
+ return result;
+}
+
+PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, int i)
+{
+ UChar buf[1 + sizeof(i) * 3];
+ UChar* end = buf + sizeof(buf) / sizeof(UChar);
+ UChar* p = end;
+
+ if (i == 0)
+ *--p = '0';
+ else if (i == INT_MIN) {
+ char minBuf[1 + sizeof(i) * 3];
+ sprintf(minBuf, "%d", INT_MIN);
+ return concatenate(rep, minBuf);
+ } else {
+ bool negative = false;
+ if (i < 0) {
+ negative = true;
+ i = -i;
+ }
+ while (i) {
+ *--p = static_cast<unsigned short>((i % 10) + '0');
+ i /= 10;
+ }
+ if (negative)
+ *--p = '-';
+ }
+
+ return concatenate(rep, p, static_cast<int>(end - p));
+
+}
+
+PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
+{
+ // avoid ever printing -NaN, in JS conceptually there is only one NaN value
+ if (isnan(d))
+ return concatenate(rep, "NaN");
+
+ if (d == 0.0) // stringify -0 as 0
+ d = 0.0;
+
+ char buf[80];
+ int decimalPoint;
+ int sign;
+
+ char result[80];
+ WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
+ int length = static_cast<int>(strlen(result));
+
+ int i = 0;
+ if (sign)
+ buf[i++] = '-';
+
+ if (decimalPoint <= 0 && decimalPoint > -6) {
+ buf[i++] = '0';
+ buf[i++] = '.';
+ for (int j = decimalPoint; j < 0; j++)
+ buf[i++] = '0';
+ strcpy(buf + i, result);
+ } else if (decimalPoint <= 21 && decimalPoint > 0) {
+ if (length <= decimalPoint) {
+ strcpy(buf + i, result);
+ i += length;
+ for (int j = 0; j < decimalPoint - length; j++)
+ buf[i++] = '0';
+ buf[i] = '\0';
+ } else {
+ strncpy(buf + i, result, decimalPoint);
+ i += decimalPoint;
+ buf[i++] = '.';
+ strcpy(buf + i, result + decimalPoint);
+ }
+ } else if (result[0] < '0' || result[0] > '9')
+ strcpy(buf + i, result);
+ else {
+ buf[i++] = result[0];
+ if (length > 1) {
+ buf[i++] = '.';
+ strcpy(buf + i, result + 1);
+ i += length - 1;
+ }
+
+ buf[i++] = 'e';
+ buf[i++] = (decimalPoint >= 0) ? '+' : '-';
+ // decimalPoint can't be more than 3 digits decimal given the
+ // nature of float representation
+ int exponential = decimalPoint - 1;
+ if (exponential < 0)
+ exponential = -exponential;
+ 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);
+ buf[i++] = '\0';
+ }
+
+ return concatenate(rep, buf);
+}
+
+UString UString::from(int i)
+{
+ UChar buf[1 + sizeof(i) * 3];
+ UChar* end = buf + sizeof(buf) / sizeof(UChar);
+ UChar* p = end;
+
+ if (i == 0)
+ *--p = '0';
+ else if (i == INT_MIN) {
+ char minBuf[1 + sizeof(i) * 3];
+ sprintf(minBuf, "%d", INT_MIN);
+ return UString(minBuf);
+ } else {
+ bool negative = false;
+ if (i < 0) {
+ negative = true;
+ i = -i;
+ }
+ while (i) {
+ *--p = static_cast<unsigned short>((i % 10) + '0');
+ i /= 10;
+ }
+ if (negative)
+ *--p = '-';
+ }
+
+ return UString(p, static_cast<int>(end - p));
+}
+
+#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC)
+UString UString::from(int64_t i)
+{
+ UChar buf[1 + sizeof(i) * 3];
+ UChar* end = buf + sizeof(buf) / sizeof(UChar);
+ UChar* p = end;
+
+ if (i == 0)
+ *--p = '0';
+ else if (i == LLONG_MIN) {
+ char minBuf[1 + sizeof(i) * 3];
+ snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", LLONG_MIN);
+ return UString(minBuf);
+ } else {
+ bool negative = false;
+ if (i < 0) {
+ negative = true;
+ i = -i;
+ }
+ while (i) {
+ *--p = static_cast<unsigned short>((i % 10) + '0');
+ i /= 10;
+ }
+ if (negative)
+ *--p = '-';
+ }
+
+ return UString(p, static_cast<int>(end - p));
+}
+#endif
+
+UString UString::from(unsigned int u)
+{
+ UChar buf[sizeof(u) * 3];
+ UChar* end = buf + sizeof(buf) / sizeof(UChar);
+ UChar* p = end;
+
+ if (u == 0)
+ *--p = '0';
+ else {
+ while (u) {
+ *--p = static_cast<unsigned short>((u % 10) + '0');
+ u /= 10;
+ }
+ }
+
+ return UString(p, static_cast<int>(end - p));
+}
+
+UString UString::from(long l)
+{
+ UChar buf[1 + sizeof(l) * 3];
+ UChar* end = buf + sizeof(buf) / sizeof(UChar);
+ UChar* p = end;
+
+ if (l == 0)
+ *--p = '0';
+ else if (l == LONG_MIN) {
+ char minBuf[1 + sizeof(l) * 3];
+ sprintf(minBuf, "%ld", LONG_MIN);
+ return UString(minBuf);
+ } else {
+ bool negative = false;
+ if (l < 0) {
+ negative = true;
+ l = -l;
+ }
+ while (l) {
+ *--p = static_cast<unsigned short>((l % 10) + '0');
+ l /= 10;
+ }
+ if (negative)
+ *--p = '-';
+ }
+
+ return UString(p, static_cast<int>(end - p));
+}
+
+UString UString::from(double d)
+{
+ // avoid ever printing -NaN, in JS conceptually there is only one NaN value
+ if (isnan(d))
+ return "NaN";
+
+ char buf[80];
+ int decimalPoint;
+ int sign;
+
+ char result[80];
+ WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
+ int length = static_cast<int>(strlen(result));
+
+ int i = 0;
+ if (sign)
+ buf[i++] = '-';
+
+ if (decimalPoint <= 0 && decimalPoint > -6) {
+ buf[i++] = '0';
+ buf[i++] = '.';
+ for (int j = decimalPoint; j < 0; j++)
+ buf[i++] = '0';
+ strcpy(buf + i, result);
+ } else if (decimalPoint <= 21 && decimalPoint > 0) {
+ if (length <= decimalPoint) {
+ strcpy(buf + i, result);
+ i += length;
+ for (int j = 0; j < decimalPoint - length; j++)
+ buf[i++] = '0';
+ buf[i] = '\0';
+ } else {
+ strncpy(buf + i, result, decimalPoint);
+ i += decimalPoint;
+ buf[i++] = '.';
+ strcpy(buf + i, result + decimalPoint);
+ }
+ } else if (result[0] < '0' || result[0] > '9')
+ strcpy(buf + i, result);
+ else {
+ buf[i++] = result[0];
+ if (length > 1) {
+ buf[i++] = '.';
+ strcpy(buf + i, result + 1);
+ i += length - 1;
+ }
+
+ buf[i++] = 'e';
+ buf[i++] = (decimalPoint >= 0) ? '+' : '-';
+ // decimalPoint can't be more than 3 digits decimal given the
+ // nature of float representation
+ int exponential = decimalPoint - 1;
+ if (exponential < 0)
+ exponential = -exponential;
+ 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);
+ buf[i++] = '\0';
+ }
+
+ return UString(buf);
+}
+
+UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
+{
+ m_rep->checkConsistency();
+
+ if (rangeCount == 1 && separatorCount == 0) {
+ int thisSize = size();
+ int position = substringRanges[0].position;
+ int length = substringRanges[0].length;
+ if (position <= 0 && length >= thisSize)
+ return *this;
+ return UString::Rep::create(m_rep, max(0, position), min(thisSize, length));
+ }
+
+ int totalLength = 0;
+ for (int i = 0; i < rangeCount; i++)
+ totalLength += substringRanges[i].length;
+ for (int i = 0; i < separatorCount; i++)
+ totalLength += separators[i].size();
+
+ if (totalLength == 0)
+ return "";
+
+ UChar* buffer = allocChars(totalLength);
+ if (!buffer)
+ return null();
+
+ int maxCount = max(rangeCount, separatorCount);
+ int bufferPos = 0;
+ for (int i = 0; i < maxCount; i++) {
+ if (i < rangeCount) {
+ copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);
+ bufferPos += substringRanges[i].length;
+ }
+ if (i < separatorCount) {
+ copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
+ bufferPos += separators[i].size();
+ }
+ }
+
+ return UString::Rep::create(buffer, totalLength);
+}
+
+UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const
+{
+ m_rep->checkConsistency();
+
+ int replacementLength = replacement.size();
+ int totalLength = size() - rangeLength + replacementLength;
+ if (totalLength == 0)
+ return "";
+
+ UChar* buffer = allocChars(totalLength);
+ if (!buffer)
+ return null();
+
+ copyChars(buffer, data(), rangeStart);
+ copyChars(buffer + rangeStart, replacement.data(), replacementLength);
+ int rangeEnd = rangeStart + rangeLength;
+ copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd);
+
+ return UString::Rep::create(buffer, totalLength);
+}
+
+
+UString& UString::append(const UString &t)
+{
+ m_rep->checkConsistency();
+ t.rep()->checkConsistency();
+
+ int thisSize = size();
+ int thisOffset = m_rep->offset;
+ int tSize = t.size();
+ int length = thisSize + tSize;
+ BaseString* base = m_rep->baseString();
+
+ // possible cases:
+ if (thisSize == 0) {
+ // this is empty
+ *this = t;
+ } else if (tSize == 0) {
+ // t is empty
+ } else if (m_rep == base && !base->isShared()) {
+ // this is direct and has refcount of 1 (so we can just alter it directly)
+ expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
+ if (data()) {
+ copyChars(m_rep->data() + thisSize, t.data(), tSize);
+ m_rep->len = length;
+ m_rep->_hash = 0;
+ }
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
+ // this reaches the end of the buffer - extend it if it's long enough to append to
+ expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
+ if (data()) {
+ copyChars(m_rep->data() + thisSize, t.data(), tSize);
+ m_rep = Rep::create(m_rep, 0, length);
+ }
+ } else {
+ // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
+ size_t newCapacity = expandedSize(length, 0);
+ UChar* d = allocChars(newCapacity);
+ if (!d)
+ makeNull();
+ else {
+ copyChars(d, data(), thisSize);
+ copyChars(d + thisSize, t.data(), tSize);
+ m_rep = Rep::create(d, length);
+ m_rep->baseString()->capacity = newCapacity;
+ }
+ }
+
+ m_rep->checkConsistency();
+ t.rep()->checkConsistency();
+
+ return *this;
+}
+
+UString& UString::append(const UChar* tData, int tSize)
+{
+ m_rep = concatenate(m_rep.release(), tData, tSize);
+ return *this;
+}
+
+UString& UString::appendNumeric(int i)
+{
+ m_rep = concatenate(rep(), i);
+ return *this;
+}
+
+UString& UString::appendNumeric(double d)
+{
+ m_rep = concatenate(rep(), d);
+ return *this;
+}
+
+UString& UString::append(const char* t)
+{
+ m_rep = concatenate(m_rep.release(), t);
+ return *this;
+}
+
+UString& UString::append(UChar c)
+{
+ m_rep->checkConsistency();
+
+ int thisOffset = m_rep->offset;
+ int length = size();
+ BaseString* base = m_rep->baseString();
+
+ // possible cases:
+ if (length == 0) {
+ // this is empty - must make a new m_rep because we don't want to pollute the shared empty one
+ size_t newCapacity = expandedSize(1, 0);
+ UChar* d = allocChars(newCapacity);
+ if (!d)
+ makeNull();
+ else {
+ d[0] = c;
+ m_rep = Rep::create(d, 1);
+ m_rep->baseString()->capacity = newCapacity;
+ }
+ } else if (m_rep == base && !base->isShared()) {
+ // this is direct and has refcount of 1 (so we can just alter it directly)
+ expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
+ UChar* d = m_rep->data();
+ if (d) {
+ d[length] = c;
+ m_rep->len = length + 1;
+ m_rep->_hash = 0;
+ }
+ } else if (thisOffset + length == base->usedCapacity && length >= minShareSize && !base->isBufferReadOnly()) {
+ // this reaches the end of the string - extend it and share
+ expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
+ UChar* d = m_rep->data();
+ if (d) {
+ d[length] = c;
+ m_rep = Rep::create(m_rep, 0, length + 1);
+ }
+ } else {
+ // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
+ size_t newCapacity = expandedSize(length + 1, 0);
+ UChar* d = allocChars(newCapacity);
+ if (!d)
+ makeNull();
+ else {
+ copyChars(d, data(), length);
+ d[length] = c;
+ m_rep = Rep::create(d, length + 1);
+ m_rep->baseString()->capacity = newCapacity;
+ }
+ }
+
+ m_rep->checkConsistency();
+
+ return *this;
+}
+
+bool UString::getCString(CStringBuffer& buffer) const
+{
+ int length = size();
+ int neededSize = length + 1;
+ buffer.resize(neededSize);
+ char* buf = buffer.data();
+
+ UChar ored = 0;
+ const UChar* p = data();
+ char* q = buf;
+ const UChar* limit = p + length;
+ while (p != limit) {
+ UChar c = p[0];
+ ored |= c;
+ *q = static_cast<char>(c);
+ ++p;
+ ++q;
+ }
+ *q = '\0';
+
+ return !(ored & 0xFF00);
+}
+
+char* UString::ascii() const
+{
+ int length = size();
+ int neededSize = length + 1;
+ delete[] statBuffer;
+ statBuffer = new char[neededSize];
+
+ const UChar* p = data();
+ char* q = statBuffer;
+ const UChar* limit = p + length;
+ while (p != limit) {
+ *q = static_cast<char>(p[0]);
+ ++p;
+ ++q;
+ }
+ *q = '\0';
+
+ return statBuffer;
+}
+
+UString& UString::operator=(const char* c)
+{
+ if (!c) {
+ m_rep = &Rep::null();
+ return *this;
+ }
+
+ if (!c[0]) {
+ m_rep = &Rep::empty();
+ return *this;
+ }
+
+ int l = static_cast<int>(strlen(c));
+ UChar* d;
+ BaseString* base = m_rep->baseString();
+ if (!base->isShared() && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
+ d = base->buf;
+ m_rep->_hash = 0;
+ m_rep->len = l;
+ } else {
+ d = allocChars(l);
+ if (!d) {
+ makeNull();
+ return *this;
+ }
+ m_rep = Rep::create(d, l);
+ }
+ for (int i = 0; i < l; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+
+ return *this;
+}
+
+bool UString::is8Bit() const
+{
+ const UChar* u = data();
+ const UChar* limit = u + size();
+ while (u < limit) {
+ if (u[0] > 0xFF)
+ return false;
+ ++u;
+ }
+
+ return true;
+}
+
+UChar UString::operator[](int pos) const
+{
+ if (pos >= size())
+ return '\0';
+ return data()[pos];
+}
+
+double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
+{
+ if (size() == 1) {
+ UChar c = data()[0];
+ if (isASCIIDigit(c))
+ return c - '0';
+ if (isASCIISpace(c) && tolerateEmptyString)
+ return 0;
+ return NaN;
+ }
+
+ // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
+ // after the number, so this is too strict a check.
+ CStringBuffer s;
+ if (!getCString(s))
+ return NaN;
+ const char* c = s.data();
+
+ // skip leading white space
+ while (isASCIISpace(*c))
+ c++;
+
+ // empty string ?
+ if (*c == '\0')
+ return tolerateEmptyString ? 0.0 : NaN;
+
+ double d;
+
+ // hex number ?
+ if (*c == '0' && (*(c + 1) == 'x' || *(c + 1) == 'X')) {
+ const char* firstDigitPosition = c + 2;
+ c++;
+ d = 0.0;
+ while (*(++c)) {
+ if (*c >= '0' && *c <= '9')
+ d = d * 16.0 + *c - '0';
+ else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
+ d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
+ else
+ break;
+ }
+
+ if (d >= mantissaOverflowLowerBound)
+ d = parseIntOverflow(firstDigitPosition, c - firstDigitPosition, 16);
+ } else {
+ // regular number ?
+ char* end;
+ d = WTF::strtod(c, &end);
+ if ((d != 0.0 || end != c) && d != Inf && d != -Inf) {
+ c = end;
+ } else {
+ double sign = 1.0;
+
+ if (*c == '+')
+ c++;
+ else if (*c == '-') {
+ sign = -1.0;
+ c++;
+ }
+
+ // We used strtod() to do the conversion. However, strtod() handles
+ // infinite values slightly differently than JavaScript in that it
+ // converts the string "inf" with any capitalization to infinity,
+ // whereas the ECMA spec requires that it be converted to NaN.
+
+ if (c[0] == 'I' && c[1] == 'n' && c[2] == 'f' && c[3] == 'i' && c[4] == 'n' && c[5] == 'i' && c[6] == 't' && c[7] == 'y') {
+ d = sign * Inf;
+ c += 8;
+ } else if ((d == Inf || d == -Inf) && *c != 'I' && *c != 'i')
+ c = end;
+ else
+ return NaN;
+ }
+ }
+
+ // allow trailing white space
+ while (isASCIISpace(*c))
+ c++;
+ // don't allow anything after - unless tolerant=true
+ if (!tolerateTrailingJunk && *c != '\0')
+ d = NaN;
+
+ return d;
+}
+
+double UString::toDouble(bool tolerateTrailingJunk) const
+{
+ return toDouble(tolerateTrailingJunk, true);
+}
+
+double UString::toDouble() const
+{
+ return toDouble(false, true);
+}
+
+uint32_t UString::toUInt32(bool* ok) const
+{
+ double d = toDouble();
+ bool b = true;
+
+ if (d != static_cast<uint32_t>(d)) {
+ b = false;
+ d = 0;
+ }
+
+ if (ok)
+ *ok = b;
+
+ return static_cast<uint32_t>(d);
+}
+
+uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const
+{
+ double d = toDouble(false, tolerateEmptyString);
+ bool b = true;
+
+ if (d != static_cast<uint32_t>(d)) {
+ b = false;
+ d = 0;
+ }
+
+ if (ok)
+ *ok = b;
+
+ return static_cast<uint32_t>(d);
+}
+
+uint32_t UString::toStrictUInt32(bool* ok) const
+{
+ if (ok)
+ *ok = false;
+
+ // Empty string is not OK.
+ int len = m_rep->len;
+ if (len == 0)
+ return 0;
+ const UChar* p = m_rep->data();
+ unsigned short c = p[0];
+
+ // If the first digit is 0, only 0 itself is OK.
+ if (c == '0') {
+ if (len == 1 && ok)
+ *ok = true;
+ return 0;
+ }
+
+ // Convert to UInt32, checking for overflow.
+ uint32_t i = 0;
+ while (1) {
+ // Process character, turning it into a digit.
+ if (c < '0' || c > '9')
+ return 0;
+ const unsigned d = c - '0';
+
+ // Multiply by 10, checking for overflow out of 32 bits.
+ if (i > 0xFFFFFFFFU / 10)
+ return 0;
+ i *= 10;
+
+ // Add in the digit, checking for overflow out of 32 bits.
+ const unsigned max = 0xFFFFFFFFU - d;
+ if (i > max)
+ return 0;
+ i += d;
+
+ // Handle end of string.
+ if (--len == 0) {
+ if (ok)
+ *ok = true;
+ return i;
+ }
+
+ // Get next character.
+ c = *(++p);
+ }
+}
+
+int UString::find(const UString& f, int pos) const
+{
+ int fsz = f.size();
+
+ if (pos < 0)
+ pos = 0;
+
+ if (fsz == 1) {
+ UChar ch = f[0];
+ const UChar* end = data() + size();
+ for (const UChar* c = data() + pos; c < end; c++) {
+ if (*c == ch)
+ return static_cast<int>(c - data());
+ }
+ return -1;
+ }
+
+ int sz = size();
+ if (sz < fsz)
+ return -1;
+ if (fsz == 0)
+ return pos;
+ const UChar* end = data() + sz - fsz;
+ int fsizeminusone = (fsz - 1) * sizeof(UChar);
+ const UChar* fdata = f.data();
+ unsigned short fchar = fdata[0];
+ ++fdata;
+ for (const UChar* c = data() + pos; c <= end; c++) {
+ if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
+ return static_cast<int>(c - data());
+ }
+
+ return -1;
+}
+
+int UString::find(UChar ch, int pos) const
+{
+ if (pos < 0)
+ pos = 0;
+ const UChar* end = data() + size();
+ for (const UChar* c = data() + pos; c < end; c++) {
+ if (*c == ch)
+ return static_cast<int>(c - data());
+ }
+
+ return -1;
+}
+
+int UString::rfind(const UString& f, int pos) const
+{
+ int sz = size();
+ int fsz = f.size();
+ if (sz < fsz)
+ return -1;
+ if (pos < 0)
+ pos = 0;
+ if (pos > sz - fsz)
+ pos = sz - fsz;
+ if (fsz == 0)
+ return pos;
+ int fsizeminusone = (fsz - 1) * sizeof(UChar);
+ const UChar* fdata = f.data();
+ for (const UChar* c = data() + pos; c >= data(); c--) {
+ if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
+ return static_cast<int>(c - data());
+ }
+
+ return -1;
+}
+
+int UString::rfind(UChar ch, int pos) const
+{
+ if (isEmpty())
+ return -1;
+ if (pos + 1 >= size())
+ pos = size() - 1;
+ for (const UChar* c = data() + pos; c >= data(); c--) {
+ if (*c == ch)
+ return static_cast<int>(c - data());
+ }
+
+ return -1;
+}
+
+UString UString::substr(int pos, int len) const
+{
+ int s = size();
+
+ if (pos < 0)
+ pos = 0;
+ else if (pos >= s)
+ pos = s;
+ if (len < 0)
+ len = s;
+ if (pos + len >= s)
+ len = s - pos;
+
+ if (pos == 0 && len == s)
+ return *this;
+
+ return UString(Rep::create(m_rep, pos, len));
+}
+
+bool operator==(const UString& s1, const char *s2)
+{
+ if (s2 == 0)
+ return s1.isEmpty();
+
+ const UChar* u = s1.data();
+ const UChar* uend = u + s1.size();
+ while (u != uend && *s2) {
+ if (u[0] != (unsigned char)*s2)
+ return false;
+ s2++;
+ u++;
+ }
+
+ return u == uend && *s2 == 0;
+}
+
+bool operator<(const UString& s1, const UString& s2)
+{
+ const int l1 = s1.size();
+ const int l2 = s2.size();
+ const int lmin = l1 < l2 ? l1 : l2;
+ const UChar* c1 = s1.data();
+ const UChar* c2 = s2.data();
+ int l = 0;
+ while (l < lmin && *c1 == *c2) {
+ c1++;
+ c2++;
+ l++;
+ }
+ if (l < lmin)
+ return (c1[0] < c2[0]);
+
+ return (l1 < l2);
+}
+
+bool operator>(const UString& s1, const UString& s2)
+{
+ const int l1 = s1.size();
+ const int l2 = s2.size();
+ const int lmin = l1 < l2 ? l1 : l2;
+ const UChar* c1 = s1.data();
+ const UChar* c2 = s2.data();
+ int l = 0;
+ while (l < lmin && *c1 == *c2) {
+ c1++;
+ c2++;
+ l++;
+ }
+ if (l < lmin)
+ return (c1[0] > c2[0]);
+
+ return (l1 > l2);
+}
+
+int compare(const UString& s1, const UString& s2)
+{
+ const int l1 = s1.size();
+ const int l2 = s2.size();
+ const int lmin = l1 < l2 ? l1 : l2;
+ const UChar* c1 = s1.data();
+ const UChar* c2 = s2.data();
+ int l = 0;
+ while (l < lmin && *c1 == *c2) {
+ c1++;
+ c2++;
+ l++;
+ }
+
+ if (l < lmin)
+ return (c1[0] > c2[0]) ? 1 : -1;
+
+ if (l1 == l2)
+ return 0;
+
+ return (l1 > l2) ? 1 : -1;
+}
+
+bool equal(const UString::Rep* r, const UString::Rep* b)
+{
+ int length = r->len;
+ if (length != b->len)
+ return false;
+ const UChar* d = r->data();
+ const UChar* s = b->data();
+ for (int i = 0; i != length; ++i) {
+ if (d[i] != s[i])
+ return false;
+ }
+ return true;
+}
+
+CString UString::UTF8String(bool strict) const
+{
+ // Allocate a buffer big enough to hold all the characters.
+ const int length = size();
+ Vector<char, 1024> buffer(length * 3);
+
+ // Convert to runs of 8-bit characters.
+ char* p = buffer.data();
+ const UChar* d = reinterpret_cast<const UChar*>(&data()[0]);
+ ConversionResult result = convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size(), strict);
+ if (result != conversionOK)
+ return CString();
+
+ return CString(buffer.data(), p - buffer.data());
+}
+
+// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
+NEVER_INLINE void UString::makeNull()
+{
+ m_rep = &Rep::null();
+}
+
+// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
+NEVER_INLINE UString::Rep* UString::nullRep()
+{
+ return &Rep::null();
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h
new file mode 100644
index 0000000..ab64f52
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h
@@ -0,0 +1,604 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google 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 UString_h
+#define UString_h
+
+#include "Collector.h"
+#include <stdint.h>
+#include <string.h>
+#include <wtf/Assertions.h>
+#include <wtf/CrossThreadRefCounted.h>
+#include <wtf/OwnFastMallocPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/PtrAndFlags.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace JSC {
+
+ using WTF::PlacementNewAdoptType;
+ using WTF::PlacementNewAdopt;
+
+ class IdentifierTable;
+
+ class CString {
+ public:
+ CString()
+ : m_length(0)
+ , m_data(0)
+ {
+ }
+
+ CString(const char*);
+ CString(const char*, size_t);
+ CString(const CString&);
+
+ ~CString();
+
+ static CString adopt(char*, size_t); // buffer should be allocated with new[].
+
+ CString& append(const CString&);
+ CString& operator=(const char* c);
+ CString& operator=(const CString&);
+ CString& operator+=(const CString& c) { return append(c); }
+
+ size_t size() const { return m_length; }
+ const char* c_str() const { return m_data; }
+
+ private:
+ size_t m_length;
+ char* m_data;
+ };
+
+ typedef Vector<char, 32> CStringBuffer;
+
+ class UString {
+ friend class JIT;
+
+ public:
+
+ typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
+ struct BaseString;
+ struct Rep : Noncopyable {
+ friend class JIT;
+
+ static PassRefPtr<Rep> create(UChar* buffer, int length)
+ {
+ return adoptRef(new BaseString(buffer, length));
+ }
+
+ static PassRefPtr<Rep> createEmptyBuffer(size_t size)
+ {
+ // Guard against integer overflow
+ if (size < (std::numeric_limits<size_t>::max() / sizeof(UChar))) {
+ if (void * buf = tryFastMalloc(size * sizeof(UChar)))
+ return adoptRef(new BaseString(static_cast<UChar*>(buf), 0, size));
+ }
+ return adoptRef(new BaseString(0, 0, 0));
+ }
+
+ static PassRefPtr<Rep> createCopying(const UChar*, int);
+ static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length);
+
+ // Constructs a string from a UTF-8 string, using strict conversion (see comments in UTF8.h).
+ // Returns UString::Rep::null for null input or conversion failure.
+ static PassRefPtr<Rep> createFromUTF8(const char*);
+
+ // Uses SharedUChar to have joint ownership over the UChar*.
+ static PassRefPtr<Rep> create(UChar*, int, PassRefPtr<SharedUChar>);
+
+ SharedUChar* sharedBuffer();
+ void destroy();
+
+ bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); }
+ UChar* data() const;
+ int size() const { return len; }
+
+ unsigned hash() const { if (_hash == 0) _hash = computeHash(data(), len); return _hash; }
+ unsigned computedHash() const { ASSERT(_hash); return _hash; } // fast path for Identifiers
+
+ static unsigned computeHash(const UChar*, int length);
+ static unsigned computeHash(const char*, int length);
+ static unsigned computeHash(const char* s) { return computeHash(s, strlen(s)); }
+
+ IdentifierTable* identifierTable() const { return m_identifierTableAndFlags.get(); }
+ void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTableAndFlags.set(table); }
+
+ bool isStatic() const { return m_identifierTableAndFlags.isFlagSet(StaticFlag); }
+ void setStatic(bool);
+ void setBaseString(PassRefPtr<BaseString>);
+ BaseString* baseString();
+ const BaseString* baseString() const;
+
+ Rep* ref() { ++rc; return this; }
+ ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); }
+
+ void checkConsistency() const;
+ enum UStringFlags {
+ StaticFlag,
+ BaseStringFlag
+ };
+
+ // unshared data
+ int offset;
+ int len;
+ int rc; // For null and empty static strings, this field does not reflect a correct count, because ref/deref are not thread-safe. A special case in destroy() guarantees that these do not get deleted.
+ mutable unsigned _hash;
+ PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
+
+ static BaseString& null() { return *nullBaseString; }
+ static BaseString& empty() { return *emptyBaseString; }
+
+ bool reserveCapacity(int capacity);
+
+ protected:
+ // Constructor for use by BaseString subclass; they use the union with m_baseString for another purpose.
+ Rep(int length)
+ : offset(0)
+ , len(length)
+ , rc(1)
+ , _hash(0)
+ , m_baseString(0)
+ {
+ }
+
+ Rep(PassRefPtr<BaseString> base, int offsetInBase, int length)
+ : offset(offsetInBase)
+ , len(length)
+ , rc(1)
+ , _hash(0)
+ , m_baseString(base.releaseRef())
+ {
+ checkConsistency();
+ }
+
+ union {
+ // If !baseIsSelf()
+ BaseString* m_baseString;
+ // If baseIsSelf()
+ SharedUChar* m_sharedBuffer;
+ };
+
+ private:
+ // For SmallStringStorage which allocates an array and does initialization manually.
+ Rep() { }
+
+ friend class SmallStringsStorage;
+ friend void initializeUString();
+ JS_EXPORTDATA static BaseString* nullBaseString;
+ JS_EXPORTDATA static BaseString* emptyBaseString;
+ };
+
+
+ struct BaseString : public Rep {
+ bool isShared() { return rc != 1 || isBufferReadOnly(); }
+ void setSharedBuffer(PassRefPtr<SharedUChar>);
+
+ bool isBufferReadOnly()
+ {
+ if (!m_sharedBuffer)
+ return false;
+ return slowIsBufferReadOnly();
+ }
+
+ // potentially shared data.
+ UChar* buf;
+ int preCapacity;
+ int usedPreCapacity;
+ int capacity;
+ int usedCapacity;
+
+ size_t reportedCost;
+
+ private:
+ BaseString(UChar* buffer, int length, int additionalCapacity = 0)
+ : Rep(length)
+ , buf(buffer)
+ , preCapacity(0)
+ , usedPreCapacity(0)
+ , capacity(length + additionalCapacity)
+ , usedCapacity(length)
+ , reportedCost(0)
+ {
+ m_identifierTableAndFlags.setFlag(BaseStringFlag);
+ checkConsistency();
+ }
+
+ SharedUChar* sharedBuffer();
+ bool slowIsBufferReadOnly();
+
+ friend struct Rep;
+ friend class SmallStringsStorage;
+ friend void initializeUString();
+ };
+
+ public:
+ UString();
+ UString(const char*);
+ UString(const UChar*, int length);
+ UString(UChar*, int length, bool copy);
+
+ UString(const UString& s)
+ : m_rep(s.m_rep)
+ {
+ }
+
+ UString(const Vector<UChar>& buffer);
+
+ ~UString()
+ {
+ }
+
+ // Special constructor for cases where we overwrite an object in place.
+ UString(PlacementNewAdoptType)
+ : m_rep(PlacementNewAdopt)
+ {
+ }
+
+ static UString from(int);
+#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC)
+ static UString from(int64_t i);
+#endif
+ static UString from(unsigned int);
+ static UString from(long);
+ static UString from(double);
+
+ struct Range {
+ public:
+ Range(int pos, int len)
+ : position(pos)
+ , length(len)
+ {
+ }
+
+ Range()
+ {
+ }
+
+ int position;
+ int length;
+ };
+
+ UString spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const;
+
+ UString replaceRange(int rangeStart, int RangeEnd, const UString& replacement) const;
+
+ UString& append(const UString&);
+ UString& append(const char*);
+ UString& append(UChar);
+ UString& append(char c) { return append(static_cast<UChar>(static_cast<unsigned char>(c))); }
+ UString& append(const UChar*, int size);
+ UString& appendNumeric(int);
+ UString& appendNumeric(double);
+
+ bool getCString(CStringBuffer&) const;
+
+ // NOTE: This method should only be used for *debugging* purposes as it
+ // is neither Unicode safe nor free from side effects nor thread-safe.
+ char* ascii() const;
+
+ /**
+ * Convert the string to UTF-8, assuming it is UTF-16 encoded.
+ * In non-strict mode, this function is tolerant of badly formed UTF-16, it
+ * can create UTF-8 strings that are invalid because they have characters in
+ * the range U+D800-U+DDFF, U+FFFE, or U+FFFF, but the UTF-8 string is
+ * guaranteed to be otherwise valid.
+ * In strict mode, error is returned as null CString.
+ */
+ CString UTF8String(bool strict = false) const;
+
+ UString& operator=(const char*c);
+
+ UString& operator+=(const UString& s) { return append(s); }
+ UString& operator+=(const char* s) { return append(s); }
+
+ const UChar* data() const { return m_rep->data(); }
+
+ bool isNull() const { return (m_rep == &Rep::null()); }
+ bool isEmpty() const { return (!m_rep->len); }
+
+ bool is8Bit() const;
+
+ int size() const { return m_rep->size(); }
+
+ UChar operator[](int pos) const;
+
+ double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
+ double toDouble(bool tolerateTrailingJunk) const;
+ double toDouble() const;
+
+ uint32_t toUInt32(bool* ok = 0) const;
+ uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const;
+ uint32_t toStrictUInt32(bool* ok = 0) const;
+
+ unsigned toArrayIndex(bool* ok = 0) const;
+
+ int find(const UString& f, int pos = 0) const;
+ int find(UChar, int pos = 0) const;
+ int rfind(const UString& f, int pos) const;
+ int rfind(UChar, int pos) const;
+
+ UString substr(int pos = 0, int len = -1) const;
+
+ static const UString& null() { return *nullUString; }
+
+ Rep* rep() const { return m_rep.get(); }
+ static Rep* nullRep();
+
+ UString(PassRefPtr<Rep> r)
+ : m_rep(r)
+ {
+ ASSERT(m_rep);
+ }
+
+ size_t cost() const;
+
+ // Attempt to grow this string such that it can grow to a total length of 'capacity'
+ // without reallocation. This may fail a number of reasons - if the BasicString is
+ // shared and another string is using part of the capacity beyond our end point, if
+ // the realloc fails, or if this string is empty and has no storage.
+ //
+ // This method returns a boolean indicating success.
+ bool reserveCapacity(int capacity)
+ {
+ return m_rep->reserveCapacity(capacity);
+ }
+
+#if PLATFORM(QT)
+ operator QT_PREPEND_NAMESPACE(QString)() const
+ {
+ QT_USE_NAMESPACE;
+ return QString(reinterpret_cast<const QChar*>(this->data()), this->size());
+ }
+
+ UString(const QT_PREPEND_NAMESPACE(QString)& str)
+ {
+ *this = JSC::UString(reinterpret_cast<const UChar*>(str.constData()), str.length());
+ }
+#endif
+
+
+ private:
+ void expandCapacity(int requiredLength);
+ void expandPreCapacity(int requiredPreCap);
+ void makeNull();
+
+ RefPtr<Rep> m_rep;
+ static UString* nullUString;
+
+ friend void initializeUString();
+ friend bool operator==(const UString&, const UString&);
+ friend PassRefPtr<Rep> concatenate(Rep*, Rep*); // returns 0 if out of memory
+ };
+ PassRefPtr<UString::Rep> concatenate(UString::Rep*, UString::Rep*);
+ PassRefPtr<UString::Rep> concatenate(UString::Rep*, int);
+ PassRefPtr<UString::Rep> concatenate(UString::Rep*, double);
+
+ inline bool operator==(const UString& s1, const UString& s2)
+ {
+ int size = s1.size();
+ switch (size) {
+ case 0:
+ return !s2.size();
+ case 1:
+ return s2.size() == 1 && s1.data()[0] == s2.data()[0];
+ case 2: {
+ if (s2.size() != 2)
+ return false;
+ const UChar* d1 = s1.data();
+ const UChar* d2 = s2.data();
+ return (d1[0] == d2[0]) & (d1[1] == d2[1]);
+ }
+ default:
+ return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;
+ }
+ }
+
+
+ inline bool operator!=(const UString& s1, const UString& s2)
+ {
+ return !JSC::operator==(s1, s2);
+ }
+
+ bool operator<(const UString& s1, const UString& s2);
+ bool operator>(const UString& s1, const UString& s2);
+
+ bool operator==(const UString& s1, const char* s2);
+
+ inline bool operator!=(const UString& s1, const char* s2)
+ {
+ return !JSC::operator==(s1, s2);
+ }
+
+ inline bool operator==(const char *s1, const UString& s2)
+ {
+ return operator==(s2, s1);
+ }
+
+ inline bool operator!=(const char *s1, const UString& s2)
+ {
+ return !JSC::operator==(s1, s2);
+ }
+
+ bool operator==(const CString&, const CString&);
+
+ inline UString operator+(const UString& s1, const UString& s2)
+ {
+ RefPtr<UString::Rep> result = concatenate(s1.rep(), s2.rep());
+ return UString(result ? result.release() : UString::nullRep());
+ }
+
+ int compare(const UString&, const UString&);
+
+ bool equal(const UString::Rep*, const UString::Rep*);
+
+ inline PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<UString::Rep> rep, int offset, int length)
+ {
+ ASSERT(rep);
+ rep->checkConsistency();
+
+ int repOffset = rep->offset;
+
+ PassRefPtr<BaseString> base = rep->baseString();
+
+ ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
+ ASSERT(offset + repOffset + length <= base->usedCapacity);
+
+ // Steal the single reference this Rep was created with.
+ return adoptRef(new Rep(base, repOffset + offset, length));
+ }
+
+ inline UChar* UString::Rep::data() const
+ {
+ const BaseString* base = baseString();
+ return base->buf + base->preCapacity + offset;
+ }
+
+ inline void UString::Rep::setStatic(bool v)
+ {
+ ASSERT(!identifierTable());
+ if (v)
+ m_identifierTableAndFlags.setFlag(StaticFlag);
+ else
+ m_identifierTableAndFlags.clearFlag(StaticFlag);
+ }
+
+ inline void UString::Rep::setBaseString(PassRefPtr<BaseString> base)
+ {
+ ASSERT(base != this);
+ ASSERT(!baseIsSelf());
+ m_baseString = base.releaseRef();
+ }
+
+ inline UString::BaseString* UString::Rep::baseString()
+ {
+ return !baseIsSelf() ? m_baseString : reinterpret_cast<BaseString*>(this) ;
+ }
+
+ inline const UString::BaseString* UString::Rep::baseString() const
+ {
+ return const_cast<Rep*>(this)->baseString();
+ }
+
+#ifdef NDEBUG
+ inline void UString::Rep::checkConsistency() const
+ {
+ }
+#endif
+
+ inline UString::UString()
+ : m_rep(&Rep::null())
+ {
+ }
+
+ // Rule from ECMA 15.2 about what an array index is.
+ // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
+ inline unsigned UString::toArrayIndex(bool* ok) const
+ {
+ unsigned i = toStrictUInt32(ok);
+ if (ok && i >= 0xFFFFFFFFU)
+ *ok = false;
+ return i;
+ }
+
+ // We'd rather not do shared substring append for small strings, since
+ // this runs too much risk of a tiny initial string holding down a
+ // huge buffer.
+ // FIXME: this should be size_t but that would cause warnings until we
+ // fix UString sizes to be size_t instead of int
+ static const int minShareSize = Heap::minExtraCostSize / sizeof(UChar);
+
+ inline size_t UString::cost() const
+ {
+ BaseString* base = m_rep->baseString();
+ size_t capacity = (base->capacity + base->preCapacity) * sizeof(UChar);
+ size_t reportedCost = base->reportedCost;
+ ASSERT(capacity >= reportedCost);
+
+ size_t capacityDelta = capacity - reportedCost;
+
+ if (capacityDelta < static_cast<size_t>(minShareSize))
+ return 0;
+
+ base->reportedCost = capacity;
+
+ return capacityDelta;
+ }
+
+#if PLATFORM(QT)
+
+ inline UString operator+(const char* s1, const UString& s2)
+ {
+ return operator+(UString(s1), s2);
+ }
+
+ inline UString operator+(const UString& s1, const char* s2)
+ {
+ return operator+(s1, UString(s2));
+ }
+
+#endif
+
+ struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > {
+ static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->computedHash(); }
+ static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); }
+ };
+
+ void initializeUString();
+} // namespace JSC
+
+namespace WTF {
+
+ template<typename T> struct DefaultHash;
+ template<typename T> struct StrHash;
+
+ template<> struct StrHash<JSC::UString::Rep*> {
+ static unsigned hash(const JSC::UString::Rep* key) { return key->hash(); }
+ static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return JSC::equal(a, b); }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+ };
+
+ template<> struct StrHash<RefPtr<JSC::UString::Rep> > : public StrHash<JSC::UString::Rep*> {
+ using StrHash<JSC::UString::Rep*>::hash;
+ static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->hash(); }
+ using StrHash<JSC::UString::Rep*>::equal;
+ static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return JSC::equal(a.get(), b.get()); }
+ static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return JSC::equal(a, b.get()); }
+ static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return JSC::equal(a.get(), b); }
+
+ static const bool safeToCompareToEmptyOrDeleted = false;
+ };
+
+ template<> struct DefaultHash<JSC::UString::Rep*> {
+ typedef StrHash<JSC::UString::Rep*> Hash;
+ };
+
+ template<> struct DefaultHash<RefPtr<JSC::UString::Rep> > {
+ typedef StrHash<RefPtr<JSC::UString::Rep> > Hash;
+
+ };
+
+} // namespace WTF
+
+#endif