summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/runtime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2009-06-15 09:06:43 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-06-15 09:31:31 (GMT)
commitc411f16870f112c3407c28c22b617f613a82cff4 (patch)
tree29a1bcd590c8b31af2aab445bfe8a978dc5bf582 /src/3rdparty/webkit/JavaScriptCore/runtime
parent3d77b56b32a0c53ec0bbfaa07236fedb900ff336 (diff)
downloadQt-c411f16870f112c3407c28c22b617f613a82cff4.zip
Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.gz
Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.bz2
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-15062009 ( 65232bf00dc494ebfd978f998c88f58d18ecce1e )
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.cpp17
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h76
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.cpp68
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h20
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp11
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp633
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.cpp8
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/BooleanPrototype.cpp19
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.h70
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/CallData.h8
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp77
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h14
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h5
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp12
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Completion.h10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.cpp2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.h4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp91
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h6
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/DateMath.cpp146
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp410
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Error.cpp3
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ErrorConstructor.cpp6
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ErrorPrototype.cpp19
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp51
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h14
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.cpp27
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.h4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.cpp100
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h6
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.cpp8
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h8
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Identifier.cpp16
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/InitializeThreading.cpp2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.cpp20
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.cpp14
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h14
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp214
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h38
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp12
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h36
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp21
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h49
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.cpp82
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h67
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.cpp138
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h99
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp138
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h61
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp77
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.h28
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.cpp41
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.h609
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSLock.cpp54
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.cpp11
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.cpp33
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h396
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp153
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h317
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp6
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h22
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.cpp4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h8
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h14
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp25
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h373
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.cpp4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h11
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.cpp306
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.h112
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.cpp26
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.h42
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.cpp112
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NativeErrorConstructor.cpp10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NativeFunctionWrapper.h (renamed from src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.cpp)23
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.cpp34
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.cpp11
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h7
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/NumberPrototype.cpp108
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp9
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp89
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Operations.cpp84
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h411
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PropertyMapHashTable.h7
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.h44
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h76
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/PutPropertySlot.h12
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.cpp156
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.h14
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp98
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h16
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExpMatchesArray.h4
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp37
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h12
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/RegExpPrototype.cpp55
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/ScopeChain.h15
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.cpp68
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.h12
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StringConstructor.cpp17
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.cpp2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h10
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h2
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp535
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp263
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h61
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp38
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h7
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h13
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.cpp154
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.h73
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/TypeInfo.h15
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp500
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/UString.h240
127 files changed, 5933 insertions, 3239 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.cpp
index 5ead733..0b5d958 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.cpp
@@ -30,19 +30,18 @@ namespace JSC {
void ArgList::getSlice(int startIndex, ArgList& result) const
{
- ASSERT(!result.m_isReadOnly);
-
- const_iterator start = min(begin() + startIndex, end());
- result.m_vector.appendRange(start, end());
- result.m_size = result.m_vector.size();
- result.m_buffer = result.m_vector.data();
+ if (startIndex <= 0 || static_cast<unsigned>(startIndex) >= m_argCount) {
+ result = ArgList(m_args, 0);
+ return;
+ }
+ result = ArgList(m_args + startIndex, m_argCount - startIndex);
}
-void ArgList::markLists(ListSet& markSet)
+void MarkedArgumentBuffer::markLists(ListSet& markSet)
{
ListSet::iterator end = markSet.end();
for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
- ArgList* list = *it;
+ MarkedArgumentBuffer* list = *it;
iterator end2 = list->end();
for (iterator it2 = list->begin(); it2 != end2; ++it2)
@@ -51,7 +50,7 @@ void ArgList::markLists(ListSet& markSet)
}
}
-void ArgList::slowAppend(JSValuePtr v)
+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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h
index a1763e0..8e85d7f 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArgList.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007, 2008 Apple Computer, Inc.
+ * 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
@@ -31,11 +31,11 @@
namespace JSC {
- class ArgList : Noncopyable {
+ class MarkedArgumentBuffer : Noncopyable {
private:
static const unsigned inlineCapacity = 8;
typedef Vector<Register, inlineCapacity> VectorType;
- typedef HashSet<ArgList*> ListSet;
+ typedef HashSet<MarkedArgumentBuffer*> ListSet;
public:
typedef VectorType::iterator iterator;
@@ -43,7 +43,7 @@ namespace JSC {
// Constructor for a read-write list, to which you may append values.
// FIXME: Remove all clients of this API, then remove this API.
- ArgList()
+ MarkedArgumentBuffer()
: m_markSet(0)
#ifndef NDEBUG
, m_isReadOnly(false)
@@ -54,7 +54,7 @@ namespace JSC {
}
// Constructor for a read-only list whose data has already been allocated elsewhere.
- ArgList(Register* buffer, size_t size)
+ MarkedArgumentBuffer(Register* buffer, size_t size)
: m_buffer(buffer)
, m_size(size)
, m_markSet(0)
@@ -76,7 +76,7 @@ namespace JSC {
#endif
}
- ~ArgList()
+ ~MarkedArgumentBuffer()
{
if (m_markSet)
m_markSet->remove(this);
@@ -85,10 +85,10 @@ namespace JSC {
size_t size() const { return m_size; }
bool isEmpty() const { return !m_size; }
- JSValuePtr at(ExecState* exec, size_t i) const
+ JSValue at(size_t i) const
{
if (i < m_size)
- return m_buffer[i].jsValue(exec);
+ return m_buffer[i].jsValue();
return jsUndefined();
}
@@ -99,7 +99,7 @@ namespace JSC {
m_size = 0;
}
- void append(JSValuePtr v)
+ void append(JSValue v)
{
ASSERT(!m_isReadOnly);
@@ -114,8 +114,6 @@ namespace JSC {
}
}
- void getSlice(int startIndex, ArgList& result) const;
-
iterator begin() { return m_buffer; }
iterator end() { return m_buffer + m_size; }
@@ -125,7 +123,7 @@ namespace JSC {
static void markLists(ListSet&);
private:
- void slowAppend(JSValuePtr);
+ void slowAppend(JSValue);
Register* m_buffer;
size_t m_size;
@@ -156,6 +154,60 @@ namespace JSC {
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/webkit/JavaScriptCore/runtime/Arguments.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.cpp
index b0429a9..f867fe8 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.cpp
@@ -69,8 +69,50 @@ void Arguments::mark()
d->activation->mark();
}
-void Arguments::fillArgList(ExecState* exec, ArgList& args)
+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);
@@ -85,9 +127,9 @@ void Arguments::fillArgList(ExecState* exec, ArgList& args)
unsigned parametersLength = min(d->numParameters, d->numArguments);
unsigned i = 0;
for (; i < parametersLength; ++i)
- args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
+ args.append(d->registers[d->firstParameterIndex + i].jsValue());
for (; i < d->numArguments; ++i)
- args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
+ args.append(d->extraArguments[i - d->numParameters].jsValue());
return;
}
@@ -95,13 +137,13 @@ void Arguments::fillArgList(ExecState* exec, ArgList& args)
unsigned i = 0;
for (; i < parametersLength; ++i) {
if (!d->deletedArguments[i])
- args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
+ 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(exec));
+ args.append(d->extraArguments[i - d->numParameters].jsValue());
else
args.append(get(exec, i));
}
@@ -113,7 +155,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl
if (i < d->numParameters) {
slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
} else
- slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
+ slot.setValue(d->extraArguments[i - d->numParameters].jsValue());
return true;
}
@@ -128,7 +170,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
if (i < d->numParameters) {
slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
} else
- slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
+ slot.setValue(d->extraArguments[i - d->numParameters].jsValue());
return true;
}
@@ -145,28 +187,28 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
-void Arguments::put(ExecState* exec, unsigned i, JSValuePtr value, PutPropertySlot& 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] = JSValuePtr(value);
+ d->registers[d->firstParameterIndex + i] = JSValue(value);
else
- d->extraArguments[i - d->numParameters] = JSValuePtr(value);
+ 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, JSValuePtr value, PutPropertySlot& 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] = JSValuePtr(value);
+ d->registers[d->firstParameterIndex + i] = JSValue(value);
else
- d->extraArguments[i - d->numParameters] = JSValuePtr(value);
+ d->extraArguments[i - d->numParameters] = JSValue(value);
return;
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h
index ebea6ad..72697eb 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h
@@ -63,8 +63,16 @@ namespace JSC {
virtual void mark();
- void fillArgList(ExecState*, ArgList&);
+ 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)
@@ -73,7 +81,7 @@ namespace JSC {
d->registers = &activation->registerAt(0);
}
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
@@ -82,8 +90,8 @@ namespace JSC {
void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
@@ -94,9 +102,9 @@ namespace JSC {
OwnPtr<ArgumentsData> d;
};
- Arguments* asArguments(JSValuePtr);
+ Arguments* asArguments(JSValue);
- inline Arguments* asArguments(JSValuePtr value)
+ inline Arguments* asArguments(JSValue value)
{
ASSERT(asObject(value)->inherits(&Arguments::info));
return static_cast<Arguments*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp
index e63abbc..e96bdfc 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -26,6 +26,7 @@
#include "ArrayPrototype.h"
#include "JSArray.h"
+#include "JSFunction.h"
#include "Lookup.h"
namespace JSC {
@@ -45,15 +46,15 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> struct
static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
{
// a single numeric argument denotes the array size (!)
- if (args.size() == 1 && args.at(exec, 0)->isNumber()) {
- uint32_t n = args.at(exec, 0)->toUInt32(exec);
- if (n != args.at(exec, 0)->toNumber(exec))
+ 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, exec->lexicalGlobalObject()->arrayStructure(), args);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), args);
}
static JSObject* constructWithArrayConstructor(ExecState* exec, JSObject*, const ArgList& args)
@@ -68,7 +69,7 @@ ConstructType ArrayConstructor::getConstructData(ConstructData& constructData)
return ConstructTypeHost;
}
-static JSValuePtr callArrayConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callArrayConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
return constructArrayWithSizeQuirk(exec, args);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp
index 0d6ebdd..807e59a 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ * 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)
*
@@ -24,7 +24,10 @@
#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"
@@ -36,25 +39,27 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
-static JSValuePtr arrayProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncConcat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncJoin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncPop(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncPush(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncReverse(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncShift(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSlice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSort(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSplice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncUnShift(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncEvery(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncForEach(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSome(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncFilter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncMap(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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&);
}
@@ -62,6 +67,23 @@ static JSValuePtr arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, c
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};
@@ -86,6 +108,8 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a
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
*/
@@ -104,36 +128,38 @@ bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prope
// ------------------------------ Array Functions ----------------------------
// Helper function
-static JSValuePtr getProperty(ExecState* exec, JSObject* obj, unsigned index)
+static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
{
PropertySlot slot(obj);
if (!obj->getPropertySlot(exec, index, slot))
- return noValue();
+ return JSValue();
return slot.getValue(exec, index);
}
-static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValuePtr value)
+static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue value)
{
PutPropertySlot slot;
obj->put(exec, propertyName, value, slot);
}
-JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&JSArray::info))
+ if (!thisValue.isObject(&JSArray::info))
return throwError(exec, TypeError);
JSObject* thisObj = asArray(thisValue);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() > MaxReentryDepth)
- return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+ 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);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -143,11 +169,11 @@ JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVal
break;
}
- JSValuePtr element = thisObj->get(exec, k);
- if (element->isUndefinedOrNull())
+ JSValue element = thisObj->get(exec, k);
+ if (element.isUndefinedOrNull())
continue;
- UString str = element->toString(exec);
+ UString str = element.toString(exec);
strBuffer.append(str.data(), str.size());
if (!strBuffer.data()) {
@@ -162,22 +188,24 @@ JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVal
return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
-JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&JSArray::info))
+ if (!thisValue.isObject(&JSArray::info))
return throwError(exec, TypeError);
JSObject* thisObj = asArray(thisValue);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() > MaxReentryDepth)
- return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+ 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);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -187,19 +215,19 @@ JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr t
break;
}
- JSValuePtr element = thisObj->get(exec, k);
- if (element->isUndefinedOrNull())
+ JSValue element = thisObj->get(exec, k);
+ if (element.isUndefinedOrNull())
continue;
- JSObject* o = element->toObject(exec);
- JSValuePtr conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
+ JSObject* o = element.toObject(exec);
+ JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
UString str;
CallData callData;
- CallType callType = conversionFunction->getCallData(callData);
+ CallType callType = conversionFunction.getCallData(callData);
if (callType != CallTypeNone)
- str = call(exec, conversionFunction, callType, callData, element, exec->emptyList())->toString(exec);
+ str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
else
- str = element->toString(exec);
+ str = element.toString(exec);
strBuffer.append(str.data(), str.size());
if (!strBuffer.data()) {
@@ -214,13 +242,15 @@ JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr t
return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
-JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
- if (arrayVisitedElements.size() > MaxReentryDepth)
- return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+ 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)
@@ -229,9 +259,9 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
Vector<UChar, 256> strBuffer;
UChar comma = ',';
- UString separator = args.at(exec, 0)->isUndefined() ? UString(&comma, 1) : args.at(exec, 0)->toString(exec);
+ UString separator = args.at(0).isUndefined() ? UString(&comma, 1) : args.at(0).toString(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(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());
@@ -241,11 +271,11 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
break;
}
- JSValuePtr element = thisObj->get(exec, k);
- if (element->isUndefinedOrNull())
+ JSValue element = thisObj->get(exec, k);
+ if (element.isUndefinedOrNull())
continue;
- UString str = element->toString(exec);
+ UString str = element.toString(exec);
strBuffer.append(str.data(), str.size());
if (!strBuffer.data()) {
@@ -260,19 +290,19 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
-JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
JSArray* arr = constructEmptyArray(exec);
int n = 0;
- JSValuePtr curArg = thisValue->toThisObject(exec);
+ JSValue curArg = thisValue.toThisObject(exec);
ArgList::const_iterator it = args.begin();
ArgList::const_iterator end = args.end();
while (1) {
- if (curArg->isObject(&JSArray::info)) {
- JSArray* curArray = asArray(curArg);
- unsigned length = curArray->length();
+ 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 (JSValuePtr v = getProperty(exec, curArray, k))
+ if (JSValue v = getProperty(exec, curObject, k))
arr->put(exec, n, v);
n++;
}
@@ -282,21 +312,21 @@ JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue
}
if (it == end)
break;
- curArg = (*it).jsValue(exec);
+ curArg = (*it);
++it;
}
arr->setLength(n);
return arr;
}
-JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (exec->interpreter()->isJSArray(thisValue))
+ if (isJSArray(&exec->globalData(), thisValue))
return asArray(thisValue)->pop();
- JSObject* thisObj = thisValue->toThisObject(exec);
- JSValuePtr result;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ 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();
@@ -308,33 +338,33 @@ JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, c
return result;
}
-JSValuePtr arrayProtoFuncPush(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (exec->interpreter()->isJSArray(thisValue) && args.size() == 1) {
+ if (isJSArray(&exec->globalData(), thisValue) && args.size() == 1) {
JSArray* array = asArray(thisValue);
- array->push(exec, args.begin()->jsValue(exec));
+ 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);
+ JSObject* thisObj = thisValue.toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned n = 0; n < args.size(); n++)
- thisObj->put(exec, length + n, args.at(exec, n));
+ thisObj->put(exec, length + n, args.at(n));
length += args.size();
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
return jsNumber(exec, length);
}
-JSValuePtr arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+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);
+ 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;
- JSValuePtr obj2 = getProperty(exec, thisObj, lk1);
- JSValuePtr obj = getProperty(exec, thisObj, k);
+ JSValue obj2 = getProperty(exec, thisObj, lk1);
+ JSValue obj = getProperty(exec, thisObj, k);
if (obj2)
thisObj->put(exec, k, obj2);
@@ -349,19 +379,19 @@ JSValuePtr arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValuePtr thisValu
return thisObj;
}
-JSValuePtr arrayProtoFuncShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
- JSValuePtr result;
+ JSObject* thisObj = thisValue.toThisObject(exec);
+ JSValue result;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ 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 (JSValuePtr obj = getProperty(exec, thisObj, k))
+ if (JSValue obj = getProperty(exec, thisObj, k))
thisObj->put(exec, k - 1, obj);
else
thisObj->deleteProperty(exec, k - 1);
@@ -372,17 +402,17 @@ JSValuePtr arrayProtoFuncShift(ExecState* exec, JSObject*, JSValuePtr thisValue,
return result;
}
-JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+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);
+ JSObject* thisObj = thisValue.toThisObject(exec);
// We return a new array
JSArray* resObj = constructEmptyArray(exec);
- JSValuePtr result = resObj;
- double begin = args.at(exec, 0)->toInteger(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(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;
@@ -392,10 +422,10 @@ JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue,
begin = 0;
}
double end;
- if (args.at(exec, 1)->isUndefined())
+ if (args.at(1).isUndefined())
end = length;
else {
- end = args.at(exec, 1)->toInteger(exec);
+ end = args.at(1).toInteger(exec);
if (end < 0) {
end += length;
if (end < 0)
@@ -410,30 +440,32 @@ JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue,
int b = static_cast<int>(begin);
int e = static_cast<int>(end);
for (int k = b; k < e; k++, n++) {
- if (JSValuePtr v = getProperty(exec, thisObj, k))
+ if (JSValue v = getProperty(exec, thisObj, k))
resObj->put(exec, n, v);
}
resObj->setLength(n);
return result;
}
-JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValuePtr function = args.at(exec, 0);
+ JSValue function = args.at(0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (thisObj->classInfo() == &JSArray::info) {
- if (callType != CallTypeNone)
+ 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);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length)
return thisObj;
@@ -441,23 +473,23 @@ JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue,
// "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) {
- JSValuePtr iObj = thisObj->get(exec, i);
+ JSValue iObj = thisObj->get(exec, i);
unsigned themin = i;
- JSValuePtr minObj = iObj;
+ JSValue minObj = iObj;
for (unsigned j = i + 1; j < length; ++j) {
- JSValuePtr jObj = thisObj->get(exec, j);
+ JSValue jObj = thisObj->get(exec, j);
double compareResult;
- if (jObj->isUndefined())
+ if (jObj.isUndefined())
compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
- else if (minObj->isUndefined())
+ else if (minObj.isUndefined())
compareResult = -1;
else if (callType != CallTypeNone) {
- ArgList l;
+ MarkedArgumentBuffer l;
l.append(jObj);
l.append(minObj);
- compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l)->toNumber(exec);
+ compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec);
} else
- compareResult = (jObj->toString(exec) < minObj->toString(exec)) ? -1 : 1;
+ compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
if (compareResult < 0) {
themin = j;
@@ -473,17 +505,17 @@ JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue,
return thisObj;
}
-JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
// 15.4.4.12
JSArray* resObj = constructEmptyArray(exec);
- JSValuePtr result = resObj;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ JSValue result = resObj;
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!args.size())
return jsUndefined();
- int begin = args.at(exec, 0)->toUInt32(exec);
+ int begin = args.at(0).toUInt32(exec);
if (begin < 0)
begin = std::max<int>(begin + length, 0);
else
@@ -491,12 +523,12 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
unsigned deleteCount;
if (args.size() > 1)
- deleteCount = std::min<int>(std::max<int>(args.at(exec, 1)->toUInt32(exec), 0), length - begin);
+ 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 (JSValuePtr v = getProperty(exec, thisObj, k + begin))
+ if (JSValue v = getProperty(exec, thisObj, k + begin))
resObj->put(exec, k, v);
}
resObj->setLength(deleteCount);
@@ -505,7 +537,7 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
if (additionalArgs != deleteCount) {
if (additionalArgs < deleteCount) {
for (unsigned k = begin; k < length - deleteCount; ++k) {
- if (JSValuePtr v = getProperty(exec, thisObj, k + deleteCount))
+ if (JSValue v = getProperty(exec, thisObj, k + deleteCount))
thisObj->put(exec, k + additionalArgs, v);
else
thisObj->deleteProperty(exec, k + additionalArgs);
@@ -514,7 +546,7 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
thisObj->deleteProperty(exec, k - 1);
} else {
for (unsigned k = length - deleteCount; (int)k > begin; --k) {
- if (JSValuePtr obj = getProperty(exec, thisObj, k + deleteCount - 1))
+ if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
thisObj->put(exec, k + additionalArgs - 1, obj);
else
thisObj->deleteProperty(exec, k + additionalArgs - 1);
@@ -522,101 +554,138 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
}
}
for (unsigned k = 0; k < additionalArgs; ++k)
- thisObj->put(exec, k + begin, args.at(exec, k + 2));
+ thisObj->put(exec, k + begin, args.at(k + 2));
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
return result;
}
-JSValuePtr arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
// 15.4.4.13
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned nrArgs = args.size();
if (nrArgs) {
for (unsigned k = length; k > 0; --k) {
- if (JSValuePtr v = getProperty(exec, thisObj, k - 1))
+ if (JSValue v = getProperty(exec, thisObj, k - 1))
thisObj->put(exec, k + nrArgs - 1, v);
else
thisObj->deleteProperty(exec, k + nrArgs - 1);
}
}
for (unsigned k = 0; k < nrArgs; ++k)
- thisObj->put(exec, k, args.at(exec, k));
- JSValuePtr result = jsNumber(exec, length + nrArgs);
+ thisObj->put(exec, k, args.at(k));
+ JSValue result = jsNumber(exec, length + nrArgs);
putProperty(exec, thisObj, exec->propertyNames().length, result);
return result;
}
-JSValuePtr arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValuePtr function = args.at(exec, 0);
+ JSValue function = args.at(0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ 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);
- for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+ 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;
- JSValuePtr v = slot.getValue(exec, k);
+ JSValue v = slot.getValue(exec, k);
- ArgList eachArguments;
+ MarkedArgumentBuffer eachArguments;
eachArguments.append(v);
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
- JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
+ JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
- if (result->toBoolean(exec))
+ if (result.toBoolean(exec))
resultArray->put(exec, filterIndex++, v);
}
return resultArray;
}
-JSValuePtr arrayProtoFuncMap(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValuePtr function = args.at(exec, 0);
+ JSValue function = args.at(0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
JSArray* resultArray = constructEmptyArray(exec, length);
-
- for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+ 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;
- JSValuePtr v = slot.getValue(exec, k);
+ JSValue v = slot.getValue(exec, k);
- ArgList eachArguments;
+ MarkedArgumentBuffer eachArguments;
eachArguments.append(v);
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
- JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
+ JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
resultArray->put(exec, k, result);
}
@@ -628,34 +697,52 @@ JSValuePtr arrayProtoFuncMap(ExecState* exec, JSObject*, JSValuePtr thisValue, c
// 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
-JSValuePtr arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValuePtr function = args.at(exec, 0);
+ JSValue function = args.at(0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
-
- JSValuePtr result = jsBoolean(true);
-
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
- for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+ 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;
- ArgList eachArguments;
+ 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);
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (!predicateResult) {
result = jsBoolean(false);
@@ -666,25 +753,42 @@ JSValuePtr arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValuePtr thisValue,
return result;
}
-JSValuePtr arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValuePtr function = args.at(exec, 0);
+ JSValue function = args.at(0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ 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;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
- for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+ 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;
- ArgList eachArguments;
+ MarkedArgumentBuffer eachArguments;
eachArguments.append(slot.getValue(exec, k));
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
@@ -694,32 +798,50 @@ JSValuePtr arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValuePtr thisValu
return jsUndefined();
}
-JSValuePtr arrayProtoFuncSome(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValuePtr function = args.at(exec, 0);
+ JSValue function = args.at(0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
-
- JSValuePtr result = jsBoolean(false);
-
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
- for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+ 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;
- ArgList eachArguments;
+ 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);
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (predicateResult) {
result = jsBoolean(true);
@@ -729,16 +851,155 @@ JSValuePtr arrayProtoFuncSome(ExecState* exec, JSObject*, JSValuePtr thisValue,
return result;
}
-JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+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);
+ JSObject* thisObj = thisValue.toThisObject(exec);
unsigned index = 0;
- double d = args.at(exec, 1)->toInteger(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ 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) {
@@ -748,28 +1009,28 @@ JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValu
index = static_cast<unsigned>(d);
}
- JSValuePtr searchElement = args.at(exec, 0);
+ JSValue searchElement = args.at(0);
for (; index < length; ++index) {
- JSValuePtr e = getProperty(exec, thisObj, index);
+ JSValue e = getProperty(exec, thisObj, index);
if (!e)
continue;
- if (strictEqual(searchElement, e))
+ if (JSValue::strictEqual(searchElement, e))
return jsNumber(exec, index);
}
return jsNumber(exec, -1);
}
-JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+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);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
int index = length - 1;
- double d = args.at(exec, 1)->toIntegerPreserveNaN(exec);
+ double d = args.at(1).toIntegerPreserveNaN(exec);
if (d < 0) {
d += length;
@@ -779,12 +1040,12 @@ JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr this
if (d < length)
index = static_cast<int>(d);
- JSValuePtr searchElement = args.at(exec, 0);
+ JSValue searchElement = args.at(0);
for (; index >= 0; --index) {
- JSValuePtr e = getProperty(exec, thisObj, index);
+ JSValue e = getProperty(exec, thisObj, index);
if (!e)
continue;
- if (strictEqual(searchElement, e))
+ if (JSValue::strictEqual(searchElement, e))
return jsNumber(exec, index);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.cpp
index aa245bb..9fcba37 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -41,7 +41,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<Structure> st
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
- obj->setInternalValue(jsBoolean(args.at(exec, 0)->toBoolean(exec)));
+ obj->setInternalValue(jsBoolean(args.at(0).toBoolean(exec)));
return obj;
}
@@ -57,9 +57,9 @@ ConstructType BooleanConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.6.1
-static JSValuePtr callBooleanConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callBooleanConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsBoolean(args.at(exec, 0)->toBoolean(exec));
+ return jsBoolean(args.at(0).toBoolean(exec));
}
CallType BooleanConstructor::getCallData(CallData& callData)
@@ -68,7 +68,7 @@ CallType BooleanConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValuePtr immediateBooleanValue)
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue immediateBooleanValue)
{
BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
obj->setInternalValue(immediateBooleanValue);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.h
index db4e8e2..d9f51ab 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanConstructor.h
@@ -36,7 +36,7 @@ namespace JSC {
virtual CallType getCallData(CallData&);
};
- JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValuePtr);
+ JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue);
JSObject* constructBoolean(ExecState*, const ArgList&);
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h
index 68941e3..cfd55fe 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanObject.h
@@ -33,9 +33,9 @@ namespace JSC {
static const ClassInfo info;
};
- BooleanObject* asBooleanObject(JSValuePtr);
+ BooleanObject* asBooleanObject(JSValue);
- inline BooleanObject* asBooleanObject(JSValuePtr value)
+ inline BooleanObject* asBooleanObject(JSValue value)
{
ASSERT(asObject(value)->inherits(&BooleanObject::info));
return static_cast<BooleanObject*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanPrototype.cpp
index 77a7a1e..703a568 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -22,6 +22,7 @@
#include "BooleanPrototype.h"
#include "Error.h"
+#include "JSFunction.h"
#include "JSString.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
@@ -31,8 +32,8 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
// Functions
-static JSValuePtr booleanProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr booleanProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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
@@ -41,8 +42,8 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> struct
{
setInternalValue(jsBoolean(false));
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
+ 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);
}
@@ -50,7 +51,7 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> struct
// ECMA 15.6.4.2 + 15.6.4.3
-JSValuePtr booleanProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
if (thisValue == jsBoolean(false))
return jsNontrivialString(exec, "false");
@@ -58,7 +59,7 @@ JSValuePtr booleanProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisV
if (thisValue == jsBoolean(true))
return jsNontrivialString(exec, "true");
- if (!thisValue->isObject(&BooleanObject::info))
+ if (!thisValue.isObject(&BooleanObject::info))
return throwError(exec, TypeError);
if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
@@ -68,12 +69,12 @@ JSValuePtr booleanProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisV
return jsNontrivialString(exec, "true");
}
-JSValuePtr booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (JSImmediate::isBoolean(thisValue))
+ if (thisValue.isBoolean())
return thisValue;
- if (!thisValue->isObject(&BooleanObject::info))
+ if (!thisValue.isObject(&BooleanObject::info))
return throwError(exec, TypeError);
return asBooleanObject(thisValue)->internalValue();
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.h
deleted file mode 100644
index 7448942..0000000
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 ByteArray_h
-#define ByteArray_h
-
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace JSC {
- class ByteArray : public RefCounted<ByteArray> {
- public:
- unsigned length() const { return m_size; }
-
- void set(unsigned index, double value)
- {
- if (index >= m_size)
- return;
- if (!(value > 0)) // Clamp NaN to 0
- value = 0;
- else if (value > 255)
- value = 255;
- m_data[index] = static_cast<unsigned char>(value + 0.5);
- }
-
- bool get(unsigned index, unsigned char& result) const
- {
- if (index >= m_size)
- return false;
- result = m_data[index];
- return true;
- }
-
- unsigned char* data() { return m_data; }
-
- static PassRefPtr<ByteArray> create(size_t size);
-
- private:
- ByteArray(size_t size)
- : m_size(size)
- {
- }
- size_t m_size;
- unsigned char m_data[sizeof(size_t)];
- };
-}
-
-#endif
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp
index fbb6392..62e42fe 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.cpp
@@ -30,7 +30,7 @@
namespace JSC {
-JSValuePtr call(ExecState* exec, JSValuePtr functionObject, CallType callType, const CallData& callData, JSValuePtr thisValue, const ArgList& args)
+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);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.h b/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.h
index b8d84cd..d5b0172 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/CallData.h
@@ -29,13 +29,15 @@
#ifndef CallData_h
#define CallData_h
+#include "NativeFunctionWrapper.h"
+
namespace JSC {
class ArgList;
class ExecState;
class FunctionBodyNode;
class JSObject;
- class JSValuePtr;
+ class JSValue;
class ScopeChainNode;
enum CallType {
@@ -44,7 +46,7 @@ namespace JSC {
CallTypeJS
};
- typedef JSValuePtr (*NativeFunction)(ExecState*, JSObject*, JSValuePtr thisValue, const ArgList&);
+ typedef JSValue (JSC_HOST_CALL *NativeFunction)(ExecState*, JSObject*, JSValue thisValue, const ArgList&);
union CallData {
struct {
@@ -56,7 +58,7 @@ namespace JSC {
} js;
};
- JSValuePtr call(ExecState*, JSValuePtr functionObject, CallType, const CallData&, JSValuePtr thisValue, const ArgList&);
+ JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp
index 69cb05e..1e5eab3 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp
@@ -23,13 +23,14 @@
#include "Collector.h"
#include "ArgList.h"
-#include "CollectorHeapIterator.h"
#include "CallFrame.h"
+#include "CollectorHeapIterator.h"
+#include "Interpreter.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSString.h"
#include "JSValue.h"
-#include "Interpreter.h"
+#include "Nodes.h"
#include "Tracing.h"
#include <algorithm>
#include <setjmp.h>
@@ -37,11 +38,12 @@
#include <wtf/FastMalloc.h>
#include <wtf/HashCountedSet.h>
#include <wtf/UnusedParam.h>
+#include <wtf/VMTags.h>
#if PLATFORM(DARWIN)
-#include <mach/mach_port.h>
#include <mach/mach_init.h>
+#include <mach/mach_port.h>
#include <mach/task.h>
#include <mach/thread_act.h>
#include <mach/vm_map.h>
@@ -74,9 +76,7 @@ extern int *__libc_stack_end;
#if PLATFORM(SOLARIS)
#include <thread.h>
-#endif
-
-#if PLATFORM(OPENBSD)
+#else
#include <pthread.h>
#endif
@@ -199,7 +199,7 @@ static NEVER_INLINE CollectorBlock* allocateBlock()
#if PLATFORM(DARWIN)
vm_address_t address = 0;
// FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: <rdar://problem/6054788>.
- vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
+ 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)
// no memory map in symbian, need to hack with fastMalloc
void* address = fastMalloc(BLOCK_SIZE);
@@ -365,6 +365,9 @@ collect:
// 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*)));
@@ -483,6 +486,15 @@ static inline void* currentThreadStackBase()
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
@@ -548,15 +560,6 @@ static inline void* currentThreadStackBase()
}
return static_cast<char*>(stackBase) + stackSize;
#endif
-#elif PLATFORM(SYMBIAN)
- static void* stackBase = 0;
- if (stackBase == 0) {
- TThreadStackInfo info;
- RThread thread;
- thread.StackInfo(info);
- stackBase = (void*)info.iBase;
- }
- return (void*)stackBase;
#else
#error Need a way to get the stack base on this platform
#endif
@@ -768,7 +771,7 @@ typedef CONTEXT PlatformThreadRegisters;
#error Need a thread register struct for this platform
#endif
-size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
+static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
{
#if PLATFORM(DARWIN)
@@ -906,45 +909,45 @@ void Heap::setGCProtectNeedsLocking()
m_protectedValuesMutex.set(new Mutex);
}
-void Heap::protect(JSValuePtr k)
+void Heap::protect(JSValue k)
{
ASSERT(k);
ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
- if (JSImmediate::isImmediate(k))
+ if (!k.isCell())
return;
if (m_protectedValuesMutex)
m_protectedValuesMutex->lock();
- m_protectedValues.add(k->asCell());
+ m_protectedValues.add(k.asCell());
if (m_protectedValuesMutex)
m_protectedValuesMutex->unlock();
}
-void Heap::unprotect(JSValuePtr k)
+void Heap::unprotect(JSValue k)
{
ASSERT(k);
ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
- if (JSImmediate::isImmediate(k))
+ if (!k.isCell())
return;
if (m_protectedValuesMutex)
m_protectedValuesMutex->lock();
- m_protectedValues.remove(k->asCell());
+ m_protectedValues.remove(k.asCell());
if (m_protectedValuesMutex)
m_protectedValuesMutex->unlock();
}
-Heap* Heap::heap(JSValuePtr v)
+Heap* Heap::heap(JSValue v)
{
- if (JSImmediate::isImmediate(v))
+ if (!v.isCell())
return 0;
- return Heap::cellBlock(v->asCell())->heap;
+ return Heap::cellBlock(v.asCell())->heap;
}
void Heap::markProtectedObjects()
@@ -1084,11 +1087,13 @@ bool Heap::collect()
markStackObjectsConservatively();
markProtectedObjects();
if (m_markListSet && m_markListSet->size())
- ArgList::markLists(*m_markListSet);
- if (m_globalData->exception && !m_globalData->exception->marked())
- m_globalData->exception->mark();
+ 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();
JAVASCRIPTCORE_GC_MARKED();
@@ -1105,7 +1110,7 @@ bool Heap::collect()
size_t Heap::objectCount()
{
- return primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
+ return primaryHeap.numLiveObjects + numberHeap.numLiveObjects - m_globalData->smallStrings.count();
}
template <HeapType heapType>
@@ -1175,16 +1180,16 @@ size_t Heap::protectedObjectCount()
return result;
}
-static const char* typeName(JSCell* val)
+static const char* typeName(JSCell* cell)
{
- if (val->isString())
+ if (cell->isString())
return "string";
- if (val->isNumber())
+ if (cell->isNumber())
return "number";
- if (val->isGetterSetter())
+ if (cell->isGetterSetter())
return "gettersetter";
- ASSERT(val->isObject());
- const ClassInfo* info = static_cast<JSObject*>(val)->classInfo();
+ ASSERT(cell->isObject());
+ const ClassInfo* info = static_cast<JSObject*>(cell)->classInfo();
return info ? info->className : "Object";
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h
index ba41d60..23f9f15 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Collector.h
@@ -39,11 +39,11 @@
namespace JSC {
- class ArgList;
+ class MarkedArgumentBuffer;
class CollectorBlock;
class JSCell;
class JSGlobalData;
- class JSValuePtr;
+ class JSValue;
enum OperationInProgress { NoOperation, Allocation, Collection };
enum HeapType { PrimaryHeap, NumberHeap };
@@ -96,10 +96,10 @@ namespace JSC {
Statistics statistics() const;
void setGCProtectNeedsLocking();
- void protect(JSValuePtr);
- void unprotect(JSValuePtr);
+ void protect(JSValue);
+ void unprotect(JSValue);
- static Heap* heap(JSValuePtr); // 0 for immediate values
+ static Heap* heap(JSValue); // 0 for immediate values
size_t globalObjectCount();
size_t protectedObjectCount();
@@ -113,7 +113,7 @@ namespace JSC {
void markConservatively(void* start, void* end);
- HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
+ HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
JSGlobalData* globalData() const { return m_globalData; }
static bool isNumber(JSCell*);
@@ -147,7 +147,7 @@ namespace JSC {
OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
ProtectCountSet m_protectedValues;
- HashSet<ArgList*>* m_markListSet;
+ HashSet<MarkedArgumentBuffer*>* m_markListSet;
#if ENABLE(JSC_MULTIPLE_THREADS)
void makeUsableFromMultipleThreads();
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h b/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h
index 45b99a8..d4c5d52 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -24,7 +24,7 @@
#include "Identifier.h"
#include <wtf/Noncopyable.h>
-// ArgList of property names, passed to a macro so we can do set them up various
+// 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__) \
@@ -63,7 +63,8 @@
macro(toPrecision) \
macro(toString) \
macro(UTC) \
- macro(valueOf)
+ macro(valueOf) \
+ macro(displayName)
namespace JSC {
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp
index b4923f7..b8b1581 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.cpp
@@ -50,7 +50,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
return Completion(Normal);
}
-Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValuePtr thisValue)
+Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
{
JSLock lock(exec);
@@ -61,14 +61,14 @@ Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& s
if (!programNode)
return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
- JSObject* thisObj = (!thisValue || thisValue->isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue->toObject(exec);
+ JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
- JSValuePtr exception = noValue();
- JSValuePtr result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
+ 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, result);
+ if (exception.isObject() && asObject(exception)->isWatchdogException())
+ return Completion(Interrupted, exception);
return Completion(Throw, exception);
}
return Completion(Normal, result);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.h
index 9631b50..41c9a64 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Completion.h
@@ -39,24 +39,24 @@ namespace JSC {
*/
class Completion {
public:
- Completion(ComplType type = Normal, JSValuePtr value = noValue())
+ Completion(ComplType type = Normal, JSValue value = JSValue())
: m_type(type)
, m_value(value)
{
}
ComplType complType() const { return m_type; }
- JSValuePtr value() const { return m_value; }
- void setValue(JSValuePtr v) { m_value = v; }
+ JSValue value() const { return m_value; }
+ void setValue(JSValue v) { m_value = v; }
bool isValueCompletion() const { return m_value; }
private:
ComplType m_type;
- JSValuePtr m_value;
+ JSValue m_value;
};
Completion checkSyntax(ExecState*, const SourceCode&);
- Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValuePtr thisValue = noValue());
+ Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValue thisValue = JSValue());
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.cpp
index 7a729ae..7ee59d7 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.cpp
@@ -30,7 +30,7 @@
namespace JSC {
-JSObject* construct(ExecState* exec, JSValuePtr object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+JSObject* construct(ExecState* exec, JSValue object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
{
if (constructType == ConstructTypeHost)
return constructData.native.function(exec, asObject(object), args);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.h
index 559c1bd..9d580d5 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ConstructData.h
@@ -35,7 +35,7 @@ namespace JSC {
class ExecState;
class FunctionBodyNode;
class JSObject;
- class JSValuePtr;
+ class JSValue;
class ScopeChainNode;
enum ConstructType {
@@ -56,7 +56,7 @@ namespace JSC {
} js;
};
- JSObject* construct(ExecState*, JSValuePtr constructor, ConstructType, const ConstructData&, const ArgList&);
+ JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp
index 6510f4b..54362d0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateConstructor.cpp
@@ -25,6 +25,7 @@
#include "DateInstance.h"
#include "DateMath.h"
#include "DatePrototype.h"
+#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
#include "ObjectPrototype.h"
@@ -47,18 +48,18 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
-static JSValuePtr dateParse(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateNow(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateUTC(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum);
+ 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);
}
@@ -73,35 +74,35 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
if (numArgs == 0) // new Date() ECMA 15.9.3.3
value = getCurrentUTCTime();
else if (numArgs == 1) {
- if (args.at(exec, 0)->isObject(&DateInstance::info))
- value = asDateInstance(args.at(exec, 0))->internalNumber();
+ if (args.at(0).isObject(&DateInstance::info))
+ value = asDateInstance(args.at(0))->internalNumber();
else {
- JSValuePtr primitive = args.at(exec, 0)->toPrimitive(exec);
- if (primitive->isString())
- value = parseDate(primitive->getString());
+ JSValue primitive = args.at(0).toPrimitive(exec);
+ if (primitive.isString())
+ value = parseDate(primitive.getString());
else
- value = primitive->toNumber(exec);
+ value = primitive.toNumber(exec);
}
} else {
- if (isnan(args.at(exec, 0)->toNumber(exec))
- || isnan(args.at(exec, 1)->toNumber(exec))
- || (numArgs >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
- || (numArgs >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
- || (numArgs >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
- || (numArgs >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
- || (numArgs >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
+ 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(exec, 0)->toInt32(exec);
+ int year = args.at(0).toInt32(exec);
t.year = (year >= 0 && year <= 99) ? year : year - 1900;
- t.month = args.at(exec, 1)->toInt32(exec);
- t.monthDay = (numArgs >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
- t.hour = args.at(exec, 3)->toInt32(exec);
- t.minute = args.at(exec, 4)->toInt32(exec);
- t.second = args.at(exec, 5)->toInt32(exec);
+ t.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(exec, 6)->toNumber(exec) : 0;
+ double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
value = gregorianDateTimeToMS(t, ms, false);
}
}
@@ -123,7 +124,7 @@ ConstructType DateConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.9.2
-static JSValuePtr callDate(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
time_t localTime = time(0);
tm localTM;
@@ -138,37 +139,37 @@ CallType DateConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-static JSValuePtr dateParse(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, parseDate(args.at(exec, 0)->toString(exec)));
+ return jsNumber(exec, parseDate(args.at(0).toString(exec)));
}
-static JSValuePtr dateNow(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+static JSValue JSC_HOST_CALL dateNow(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
return jsNumber(exec, getCurrentUTCTime());
}
-static JSValuePtr dateUTC(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
int n = args.size();
- if (isnan(args.at(exec, 0)->toNumber(exec))
- || isnan(args.at(exec, 1)->toNumber(exec))
- || (n >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
- || (n >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
- || (n >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
- || (n >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
- || (n >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
+ 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(exec, 0)->toInt32(exec);
+ int year = args.at(0).toInt32(exec);
t.year = (year >= 0 && year <= 99) ? year : year - 1900;
- t.month = args.at(exec, 1)->toInt32(exec);
- t.monthDay = (n >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
- t.hour = args.at(exec, 3)->toInt32(exec);
- t.minute = args.at(exec, 4)->toInt32(exec);
- t.second = args.at(exec, 5)->toInt32(exec);
- double ms = (n >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
+ 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));
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h
index 8dbca81..0ecd1db 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateInstance.h
@@ -32,7 +32,7 @@ namespace JSC {
explicit DateInstance(PassRefPtr<Structure>);
virtual ~DateInstance();
- double internalNumber() const { return internalValue()->uncheckedGetNumber(); }
+ double internalNumber() const { return internalValue().uncheckedGetNumber(); }
bool getTime(GregorianDateTime&, int& offset) const;
bool getUTCTime(GregorianDateTime&) const;
@@ -52,9 +52,9 @@ namespace JSC {
mutable Cache* m_cache;
};
- DateInstance* asDateInstance(JSValuePtr);
+ DateInstance* asDateInstance(JSValue);
- inline DateInstance* asDateInstance(JSValuePtr value)
+ inline DateInstance* asDateInstance(JSValue value)
{
ASSERT(asObject(value)->inherits(&DateInstance::info));
return static_cast<DateInstance*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DateMath.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DateMath.cpp
index 9cfe256..2f8c88c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/DateMath.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DateMath.cpp
@@ -48,6 +48,7 @@
#include <time.h>
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
+#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
#include <wtf/StringExtras.h>
@@ -67,10 +68,6 @@
#include <sys/timeb.h>
#endif
-#if HAVE(STRINGS_H)
-#include <strings.h>
-#endif
-
using namespace WTF;
namespace JSC {
@@ -291,139 +288,10 @@ double getCurrentUTCTime()
return floor(getCurrentUTCTimeWithMicroseconds());
}
-#if PLATFORM(WIN_OS)
-
-static LARGE_INTEGER qpcFrequency;
-static bool syncedTime;
-
-static double highResUpTime()
-{
- // We use QPC, but only after sanity checking its result, due to bugs:
- // http://support.microsoft.com/kb/274323
- // http://support.microsoft.com/kb/895980
- // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)."
-
- static LARGE_INTEGER qpcLast;
- static DWORD tickCountLast;
- static bool inited;
-
- LARGE_INTEGER qpc;
- QueryPerformanceCounter(&qpc);
- DWORD tickCount = GetTickCount();
-
- if (inited) {
- __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart;
- __int64 tickCountElapsed;
- if (tickCount >= tickCountLast)
- tickCountElapsed = (tickCount - tickCountLast);
- else {
-#if COMPILER(MINGW)
- __int64 tickCountLarge = tickCount + 0x100000000ULL;
-#else
- __int64 tickCountLarge = tickCount + 0x100000000I64;
-#endif
- tickCountElapsed = tickCountLarge - tickCountLast;
- }
-
- // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms.
- // (500ms value is from http://support.microsoft.com/kb/274323)
- __int64 diff = tickCountElapsed - qpcElapsed;
- if (diff > 500 || diff < -500)
- syncedTime = false;
- } else
- inited = true;
-
- qpcLast = qpc;
- tickCountLast = tickCount;
-
- return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);;
-}
-
-static double lowResUTCTime()
-{
-#if PLATFORM(WIN_CE)
- SYSTEMTIME systemTime;
- GetSystemTime(&systemTime);
- struct tm tmtime;
- tmtime.tm_year = systemTime.wYear - 1900;
- tmtime.tm_mon = systemTime.wMonth - 1;
- tmtime.tm_mday = systemTime.wDay;
- tmtime.tm_wday = systemTime.wDayOfWeek;
- tmtime.tm_hour = systemTime.wHour;
- tmtime.tm_min = systemTime.wMinute;
- tmtime.tm_sec = systemTime.wSecond;
- time_t timet = mktime(&tmtime);
- return timet * msPerSecond + systemTime.wMilliseconds;
-#else
- struct _timeb timebuffer;
- _ftime(&timebuffer);
- return timebuffer.time * msPerSecond + timebuffer.millitm;
-#endif
-}
-
-static bool qpcAvailable()
-{
- static bool available;
- static bool checked;
-
- if (checked)
- return available;
-
- available = QueryPerformanceFrequency(&qpcFrequency);
- checked = true;
- return available;
-}
-
-#endif
-
+// Returns current time in milliseconds since 1 Jan 1970.
double getCurrentUTCTimeWithMicroseconds()
{
-#if PLATFORM(WIN_OS)
- // Use a combination of ftime and QueryPerformanceCounter.
- // ftime returns the information we want, but doesn't have sufficient resolution.
- // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals.
- // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter
- // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift.
- static bool started;
- static double syncLowResUTCTime;
- static double syncHighResUpTime;
- static double lastUTCTime;
-
- double lowResTime = lowResUTCTime();
-
- if (!qpcAvailable())
- return lowResTime;
-
- double highResTime = highResUpTime();
-
- if (!syncedTime) {
- timeBeginPeriod(1); // increase time resolution around low-res time getter
- syncLowResUTCTime = lowResTime = lowResUTCTime();
- timeEndPeriod(1); // restore time resolution
- syncHighResUpTime = highResTime;
- syncedTime = true;
- }
-
- double highResElapsed = highResTime - syncHighResUpTime;
- double utc = syncLowResUTCTime + highResElapsed;
-
- // force a clock re-sync if we've drifted
- double lowResElapsed = lowResTime - syncLowResUTCTime;
- const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy
- if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec)
- syncedTime = false;
-
- // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur)
- const double backwardTimeLimit = 2000.0;
- if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit)
- return lastUTCTime;
- lastUTCTime = utc;
-#else
- struct timeval tv;
- gettimeofday(&tv, 0);
- double utc = tv.tv_sec * msPerSecond + tv.tv_usec / 1000.0;
-#endif
- return utc;
+ return currentTime() * 1000.0;
}
void getLocalTime(const time_t* localTime, struct tm* localTM)
@@ -1047,14 +915,14 @@ UString formatTime(const GregorianDateTime &t, bool utc)
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
} else {
int offset = abs(gmtoffset(t));
- char tzname[70];
+ char timeZoneName[70];
struct tm gtm = t;
- strftime(tzname, sizeof(tzname), "%Z", &gtm);
+ strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
- if (tzname[0]) {
+ 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, tzname);
+ 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,
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp
index 79ab2a2..ff3fb19 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.cpp
@@ -23,10 +23,16 @@
#include "DatePrototype.h"
#include "DateMath.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>
@@ -58,50 +64,49 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
-static JSValuePtr dateProtoFuncGetDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetDay(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetTime(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetTime(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToDateString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToGMTString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToTimeString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToUTCString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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&);
}
@@ -109,8 +114,13 @@ static JSValuePtr dateProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const
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")
@@ -124,24 +134,24 @@ static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateForm
return defaultStyle;
}
-static UString formatLocaleDate(ExecState* exec, double time, bool includeDate, bool includeTime, const ArgList& args)
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList& args)
{
- CFDateFormatterStyle dateStyle = (includeDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
- CFDateFormatterStyle timeStyle = (includeTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+ CFDateFormatterStyle dateStyle = (format != LocaleTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+ CFDateFormatterStyle timeStyle = (format != LocaleDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
bool useCustomFormat = false;
UString customFormatString;
- UString arg0String = args.at(exec, 0)->toString(exec);
- if (arg0String == "custom" && !args.at(exec, 1)->isUndefined()) {
+ UString arg0String = args.at(0).toString(exec);
+ if (arg0String == "custom" && !args.at(1).isUndefined()) {
useCustomFormat = true;
- customFormatString = args.at(exec, 1)->toString(exec);
- } else if (includeDate && includeTime && !args.at(exec, 1)->isUndefined()) {
+ customFormatString = args.at(1).toString(exec);
+ } else if (format == LocaleDateAndTime && !args.at(1).isUndefined()) {
dateStyle = styleFromArgString(arg0String, dateStyle);
- timeStyle = styleFromArgString(args.at(exec, 1)->toString(exec), timeStyle);
- } else if (includeDate && !args.at(exec, 0)->isUndefined())
+ timeStyle = styleFromArgString(args.at(1).toString(exec), timeStyle);
+ } else if (format != LocaleTime && !args.at(0).isUndefined())
dateStyle = styleFromArgString(arg0String, dateStyle);
- else if (includeTime && !args.at(exec, 0)->isUndefined())
+ else if (format != LocaleDate && !args.at(0).isUndefined())
timeStyle = styleFromArgString(arg0String, timeStyle);
CFLocaleRef locale = CFLocaleCopyCurrent();
@@ -149,12 +159,12 @@ static UString formatLocaleDate(ExecState* exec, double time, bool includeDate,
CFRelease(locale);
if (useCustomFormat) {
- CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, (UniChar *)customFormatString.data(), customFormatString.size());
+ CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, customFormatString.data(), customFormatString.size());
CFDateFormatterSetFormat(formatter, customFormatCFString);
CFRelease(customFormatCFString);
}
- CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, time - kCFAbsoluteTimeIntervalSince1970);
+ CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, floor(timeInMilliseconds / msPerSecond) - kCFAbsoluteTimeIntervalSince1970);
CFRelease(formatter);
@@ -166,20 +176,22 @@ static UString formatLocaleDate(ExecState* exec, double time, bool includeDate,
ASSERT(length <= bufferLength);
if (length > bufferLength)
length = bufferLength;
- CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast<UniChar *>(buffer));
+ CFStringGetCharacters(string, CFRangeMake(0, length), buffer);
CFRelease(string);
- return UString(buffer, length);
+ return jsNontrivialString(exec, UString(buffer, length));
}
-#else
+#else // !PLATFORM(MAC)
-enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
-
-static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
+static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format)
{
- static const char* formatStrings[] = {"%#c", "%#x", "%X"};
+#if HAVE(LANGINFO_H)
+ static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT };
+#else
+ static const char* const formatStrings[] = { "%#c", "%#x", "%X" };
+#endif
// Offset year if needed
struct tm localTM = gdt;
@@ -188,10 +200,26 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, c
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);
@@ -211,7 +239,15 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, c
return jsNontrivialString(exec, timebuffer);
}
-#endif // PLATFORM(WIN_OS)
+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.
@@ -231,19 +267,19 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
// hours
if (maxArgs >= 4 && idx < numArgs) {
t->hour = 0;
- milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerHour;
+ milliseconds += args.at(idx++).toInt32(exec, ok) * msPerHour;
}
// minutes
if (maxArgs >= 3 && idx < numArgs && ok) {
t->minute = 0;
- milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerMinute;
+ milliseconds += args.at(idx++).toInt32(exec, ok) * msPerMinute;
}
// seconds
if (maxArgs >= 2 && idx < numArgs && ok) {
t->second = 0;
- milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerSecond;
+ milliseconds += args.at(idx++).toInt32(exec, ok) * msPerSecond;
}
if (!ok)
@@ -251,7 +287,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
// milliseconds
if (idx < numArgs) {
- double millis = args.at(exec, idx)->toNumber(exec);
+ double millis = args.at(idx).toNumber(exec);
ok = isfinite(millis);
milliseconds += millis;
} else
@@ -277,16 +313,16 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList& args, in
// years
if (maxArgs >= 3 && idx < numArgs)
- t->year = args.at(exec, idx++)->toInt32(exec, ok) - 1900;
+ t->year = args.at(idx++).toInt32(exec, ok) - 1900;
// months
if (maxArgs >= 2 && idx < numArgs && ok)
- t->month = args.at(exec, idx++)->toInt32(exec, ok);
+ t->month = args.at(idx++).toInt32(exec, ok);
// days
if (idx < numArgs && ok) {
t->monthDay = 0;
- *ms += args.at(exec, idx)->toInt32(exec, ok) * msPerDay;
+ *ms += args.at(idx).toInt32(exec, ok) * msPerDay;
}
return ok;
@@ -295,7 +331,6 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList& args, in
const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState::dateTable};
/* Source for DatePrototype.lut.h
- FIXME: We could use templates to simplify the UTC variants.
@begin dateTable
toString dateProtoFuncToString DontEnum|Function 0
toUTCString dateProtoFuncToUTCString DontEnum|Function 0
@@ -304,7 +339,7 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
toLocaleString dateProtoFuncToLocaleString DontEnum|Function 0
toLocaleDateString dateProtoFuncToLocaleDateString DontEnum|Function 0
toLocaleTimeString dateProtoFuncToLocaleTimeString DontEnum|Function 0
- valueOf dateProtoFuncValueOf DontEnum|Function 0
+ valueOf dateProtoFuncGetTime DontEnum|Function 0
getTime dateProtoFuncGetTime DontEnum|Function 0
getFullYear dateProtoFuncGetFullYear DontEnum|Function 0
getUTCFullYear dateProtoFuncGetUTCFullYear DontEnum|Function 0
@@ -343,6 +378,7 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
getYear dateProtoFuncGetYear DontEnum|Function 0
@end
*/
+
// ECMA 15.9.4
DatePrototype::DatePrototype(ExecState* exec, PassRefPtr<Structure> structure)
@@ -359,9 +395,9 @@ bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& proper
// Functions
-JSValuePtr dateProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -376,9 +412,9 @@ JSValuePtr dateProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValu
return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, utc));
}
-JSValuePtr dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -393,9 +429,9 @@ JSValuePtr dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValuePtr thisV
return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
}
-JSValuePtr dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -410,9 +446,9 @@ JSValuePtr dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValuePtr this
return jsNontrivialString(exec, formatDate(t));
}
-JSValuePtr dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -427,9 +463,9 @@ JSValuePtr dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValuePtr this
return jsNontrivialString(exec, formatTime(t, utc));
}
-JSValuePtr dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -437,23 +473,12 @@ JSValuePtr dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr th
if (isnan(milli))
return jsNontrivialString(exec, "Invalid Date");
-#if PLATFORM(MAC)
- double secs = floor(milli / msPerSecond);
- return jsNontrivialString(exec, formatLocaleDate(exec, secs, true, true, args));
-#else
- UNUSED_PARAM(args);
-
- const bool utc = false;
-
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(exec, t, LocaleDateAndTime);
-#endif
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args);
}
-JSValuePtr dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -461,23 +486,12 @@ JSValuePtr dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValuePt
if (isnan(milli))
return jsNontrivialString(exec, "Invalid Date");
-#if PLATFORM(MAC)
- double secs = floor(milli / msPerSecond);
- return jsNontrivialString(exec, formatLocaleDate(exec, secs, true, false, args));
-#else
- UNUSED_PARAM(args);
-
- const bool utc = false;
-
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(exec, t, LocaleDate);
-#endif
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args);
}
-JSValuePtr dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -485,36 +499,12 @@ JSValuePtr dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValuePt
if (isnan(milli))
return jsNontrivialString(exec, "Invalid Date");
-#if PLATFORM(MAC)
- double secs = floor(milli / msPerSecond);
- return jsNontrivialString(exec, formatLocaleDate(exec, secs, false, true, args));
-#else
- UNUSED_PARAM(args);
-
- const bool utc = false;
-
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(exec, t, LocaleTime);
-#endif
-}
-
-JSValuePtr dateProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr 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);
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args);
}
-JSValuePtr dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -525,9 +515,9 @@ JSValuePtr dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValuePtr thisValue
return jsNumber(exec, milli);
}
-JSValuePtr dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -542,9 +532,9 @@ JSValuePtr dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValuePtr thisV
return jsNumber(exec, 1900 + t.year);
}
-JSValuePtr dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -559,9 +549,9 @@ JSValuePtr dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr th
return jsNumber(exec, 1900 + t.year);
}
-JSValuePtr dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -576,9 +566,9 @@ JSValuePtr dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValuePtr thisV
return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
}
-JSValuePtr dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -593,9 +583,9 @@ JSValuePtr dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValuePtr thisValu
return jsNumber(exec, t.month);
}
-JSValuePtr dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -610,9 +600,9 @@ JSValuePtr dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisV
return jsNumber(exec, t.month);
}
-JSValuePtr dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -627,9 +617,9 @@ JSValuePtr dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValuePtr thisValue
return jsNumber(exec, t.monthDay);
}
-JSValuePtr dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -644,9 +634,9 @@ JSValuePtr dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisVa
return jsNumber(exec, t.monthDay);
}
-JSValuePtr dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -661,9 +651,9 @@ JSValuePtr dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValuePtr thisValue,
return jsNumber(exec, t.weekDay);
}
-JSValuePtr dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -678,9 +668,9 @@ JSValuePtr dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValuePtr thisVal
return jsNumber(exec, t.weekDay);
}
-JSValuePtr dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -695,9 +685,9 @@ JSValuePtr dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValuePtr thisValu
return jsNumber(exec, t.hour);
}
-JSValuePtr dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -712,9 +702,9 @@ JSValuePtr dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisV
return jsNumber(exec, t.hour);
}
-JSValuePtr dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -729,9 +719,9 @@ JSValuePtr dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValuePtr thisVa
return jsNumber(exec, t.minute);
}
-JSValuePtr dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -746,9 +736,9 @@ JSValuePtr dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thi
return jsNumber(exec, t.minute);
}
-JSValuePtr dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -763,9 +753,9 @@ JSValuePtr dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValuePtr thisVa
return jsNumber(exec, t.second);
}
-JSValuePtr dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -780,9 +770,9 @@ JSValuePtr dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thi
return jsNumber(exec, t.second);
}
-JSValuePtr dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -795,9 +785,9 @@ JSValuePtr dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr t
return jsNumber(exec, ms);
}
-JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -810,9 +800,9 @@ JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePt
return jsNumber(exec, ms);
}
-JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -827,29 +817,29 @@ JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValuePtr
return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
}
-JSValuePtr dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = timeClip(args.at(exec, 0)->toNumber(exec));
- JSValuePtr result = jsNumber(exec, milli);
+ double milli = timeClip(args.at(0).toNumber(exec));
+ JSValue result = jsNumber(exec, milli);
thisDateObj->setInternalValue(result);
return result;
}
-static JSValuePtr setNewValueFromTimeArgs(ExecState* exec, JSValuePtr thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
double milli = thisDateObj->internalNumber();
if (args.isEmpty() || isnan(milli)) {
- JSValuePtr result = jsNaN(exec);
+ JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
@@ -861,24 +851,24 @@ static JSValuePtr setNewValueFromTimeArgs(ExecState* exec, JSValuePtr thisValue,
thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
- JSValuePtr result = jsNaN(exec);
+ JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
-static JSValuePtr setNewValueFromDateArgs(ExecState* exec, JSValuePtr thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
if (args.isEmpty()) {
- JSValuePtr result = jsNaN(exec);
+ JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
@@ -898,110 +888,110 @@ static JSValuePtr setNewValueFromDateArgs(ExecState* exec, JSValuePtr thisValue,
}
if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
- JSValuePtr result = jsNaN(exec);
+ JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
-JSValuePtr dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValuePtr dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
DateInstance* thisDateObj = asDateInstance(thisValue);
if (args.isEmpty()) {
- JSValuePtr result = jsNaN(exec);
+ JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
@@ -1021,22 +1011,22 @@ JSValuePtr dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValuePtr thisValue
}
bool ok = true;
- int32_t year = args.at(exec, 0)->toInt32(exec, ok);
+ int32_t year = args.at(0).toInt32(exec, ok);
if (!ok) {
- JSValuePtr result = jsNaN(exec);
+ JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
t.year = (year > 99 || year < 0) ? year - 1900 : year;
- JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
thisDateObj->setInternalValue(result);
return result;
}
-JSValuePtr dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h
index a6bbdf2..5f4d0ec 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/DatePrototype.h
@@ -36,7 +36,7 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Error.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Error.cpp
index 5e21c8e..db1d8cc 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Error.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Error.cpp
@@ -26,6 +26,7 @@
#include "ConstructData.h"
#include "ErrorConstructor.h"
+#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "JSString.h"
@@ -72,7 +73,7 @@ JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message,
break;
}
- ArgList args;
+ MarkedArgumentBuffer args;
if (message.isEmpty())
args.append(jsString(exec, name));
else
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorConstructor.cpp
index 2e8a523..07b7e23 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -41,8 +41,8 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<Structure> struct
ErrorInstance* constructError(ExecState* exec, const ArgList& args)
{
ErrorInstance* obj = new (exec) ErrorInstance(exec->lexicalGlobalObject()->errorStructure());
- if (!args.at(exec, 0)->isUndefined())
- obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0)->toString(exec)));
+ if (!args.at(0).isUndefined())
+ obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(0).toString(exec)));
return obj;
}
@@ -58,7 +58,7 @@ ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.9.2
-static JSValuePtr callErrorConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+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);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorPrototype.cpp
index 35358f7..599390e 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "ErrorPrototype.h"
+#include "JSFunction.h"
#include "JSString.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
@@ -30,7 +31,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
-static JSValuePtr errorProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
// ECMA 15.9.4
ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
@@ -41,24 +42,24 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure,
putDirectWithoutTransition(exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
putDirectWithoutTransition(exec->propertyNames().message, jsNontrivialString(exec, "Unknown error"), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
}
-JSValuePtr errorProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
UString s = "Error";
- JSValuePtr v = thisObj->get(exec, exec->propertyNames().name);
- if (!v->isUndefined())
- s = v->toString(exec);
+ 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()) {
+ if (!v.isUndefined()) {
// Mozilla-compatible format.
s += ": ";
- s += v->toString(exec);
+ s += v.toString(exec);
}
return jsNontrivialString(exec, s);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 42ddf04..e63594c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -31,6 +31,7 @@
#include "CodeBlock.h"
#include "CallFrame.h"
+#include "JSGlobalObjectFunctions.h"
#include "JSObject.h"
#include "JSNotAnObject.h"
#include "Interpreter.h"
@@ -38,16 +39,6 @@
namespace JSC {
-static void substitute(UString& string, const UString& substring)
-{
- int position = string.find("%s");
- ASSERT(position != -1);
- UString newString = string.substr(0, position);
- newString.append(substring);
- newString.append(string.substr(position + 2));
- string = newString;
-}
-
class InterruptedExecutionError : public JSObject {
public:
InterruptedExecutionError(JSGlobalData* globalData)
@@ -56,38 +47,26 @@ public:
}
virtual bool isWatchdogException() const { return true; }
+
+ virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; }
};
-JSValuePtr createInterruptedExecutionException(JSGlobalData* globalData)
+JSValue createInterruptedExecutionException(JSGlobalData* globalData)
{
return new (globalData) InterruptedExecutionError(globalData);
}
-JSValuePtr createError(ExecState* exec, ErrorType e, const char* msg)
+static JSValue createError(ExecState* exec, ErrorType e, const char* msg)
{
return Error::create(exec, e, msg, -1, -1, 0);
}
-JSValuePtr createError(ExecState* exec, ErrorType e, const char* msg, const Identifier& label)
-{
- UString message = msg;
- substitute(message, label.ustring());
- return Error::create(exec, e, message, -1, -1, 0);
-}
-
-JSValuePtr createError(ExecState* exec, ErrorType e, const char* msg, JSValuePtr v)
-{
- UString message = msg;
- substitute(message, v->toString(exec));
- return Error::create(exec, e, message, -1, -1, 0);
-}
-
-JSValuePtr createStackOverflowError(ExecState* exec)
+JSValue createStackOverflowError(ExecState* exec)
{
return createError(exec, RangeError, "Maximum call stack size exceeded.");
}
-JSValuePtr createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
@@ -102,12 +81,10 @@ JSValuePtr createUndefinedVariableError(ExecState* exec, const Identifier& ident
return exception;
}
-bool isStrWhiteSpace(UChar c);
-
-static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValuePtr value, UString error)
+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);
+ UString errorText = value.toString(exec);
errorText.append(" is ");
errorText.append(error);
return errorText;
@@ -119,7 +96,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
errorText.append('\'');
errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
errorText.append("' [");
- errorText.append(value->toString(exec));
+ errorText.append(value.toString(exec));
errorText.append("] is ");
} else {
// No range information, so give a few characters of context
@@ -140,7 +117,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
errorText.append("near '...");
errorText.append(codeBlock->source()->getRange(start, stop));
errorText.append("...' [");
- errorText.append(value->toString(exec));
+ errorText.append(value.toString(exec));
errorText.append("] is ");
}
errorText.append(error);
@@ -148,7 +125,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
return errorText;
}
-JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
UString message = "not a valid argument for '";
message.append(op);
@@ -166,7 +143,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValuePtr va
return exception;
}
-JSObject* createNotAConstructorError(ExecState* exec, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSObject* createNotAConstructorError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
@@ -187,7 +164,7 @@ JSObject* createNotAConstructorError(ExecState* exec, JSValuePtr value, unsigned
return exception;
}
-JSValuePtr createNotAFunctionError(ExecState* exec, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSValue createNotAFunctionError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h
index d4dfdd8..09d99dc 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -40,16 +40,16 @@ namespace JSC {
class JSGlobalData;
class JSNotAnObjectErrorStub;
class JSObject;
- class JSValuePtr;
+ class JSValue;
class Node;
- JSValuePtr createInterruptedExecutionException(JSGlobalData*);
- JSValuePtr createStackOverflowError(ExecState*);
- JSValuePtr createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
+ 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, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
- JSObject* createNotAConstructorError(ExecState*, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
- JSValuePtr createNotAFunctionError(ExecState*, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
+ 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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.cpp
index e8cfe65..f4f5cc8 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -54,7 +54,7 @@ ConstructType FunctionConstructor::getConstructData(ConstructData& constructData
return ConstructTypeHost;
}
-static JSValuePtr callFunctionConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
return constructFunction(exec, args);
}
@@ -66,7 +66,7 @@ CallType FunctionConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-static FunctionBodyNode* functionBody(ProgramNode* program)
+FunctionBodyNode* extractFunctionBody(ProgramNode* program)
{
if (!program)
return 0;
@@ -75,17 +75,19 @@ static FunctionBodyNode* functionBody(ProgramNode* program)
if (children.size() != 1)
return 0;
- ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(children[0].get());
+ StatementNode* exprStatement = children[0];
+ ASSERT(exprStatement);
ASSERT(exprStatement->isExprStatement());
if (!exprStatement || !exprStatement->isExprStatement())
return 0;
- FuncExprNode* funcExpr = static_cast<FuncExprNode*>(exprStatement->expr());
+ ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
+ ASSERT(funcExpr);
ASSERT(funcExpr->isFuncExprNode());
if (!funcExpr || !funcExpr->isFuncExprNode())
return 0;
- FunctionBodyNode* body = funcExpr->body();
+ FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
ASSERT(body);
return body;
}
@@ -93,16 +95,19 @@ static FunctionBodyNode* functionBody(ProgramNode* program)
// 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(){})";
+ program = "(function() { \n})";
else if (args.size() == 1)
- program = "(function(){" + args.at(exec, 0)->toString(exec) + "})";
+ program = "(function() { " + args.at(0).toString(exec) + "\n})";
else {
- program = "(function(" + args.at(exec, 0)->toString(exec);
+ program = "(function(" + args.at(0).toString(exec);
for (size_t i = 1; i < args.size() - 1; i++)
- program += "," + args.at(exec, i)->toString(exec);
- program += "){" + args.at(exec, args.size() - 1)->toString(exec) + "})";
+ program += "," + args.at(i).toString(exec);
+ program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})";
}
int errLine;
@@ -110,7 +115,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
SourceCode source = makeSource(program, sourceURL, lineNumber);
RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
- FunctionBodyNode* body = functionBody(programNode.get());
+ FunctionBodyNode* body = extractFunctionBody(programNode.get());
if (!body)
return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.h
index e8486dc..124b354 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionConstructor.h
@@ -26,6 +26,8 @@
namespace JSC {
class FunctionPrototype;
+ class ProgramNode;
+ class FunctionBodyNode;
class FunctionConstructor : public InternalFunction {
public:
@@ -39,6 +41,8 @@ namespace JSC {
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/webkit/JavaScriptCore/runtime/FunctionPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.cpp
index 4d9d682..9ba2144 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -26,15 +26,16 @@
#include "JSFunction.h"
#include "JSString.h"
#include "Interpreter.h"
+#include "Lexer.h"
#include "PrototypeFunction.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
-static JSValuePtr functionProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionProtoFuncApply(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionProtoFuncCall(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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)
@@ -42,14 +43,16 @@ FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<Structure> stru
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
}
-void FunctionPrototype::addFunctionProperties(ExecState* exec, Structure* prototypeFunctionStructure)
+void FunctionPrototype::addFunctionProperties(ExecState* exec, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction)
{
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
+ 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 JSValuePtr callFunctionPrototype(ExecState*, JSObject*, JSValuePtr, const ArgList&)
+static JSValue JSC_HOST_CALL callFunctionPrototype(ExecState*, JSObject*, JSValue, const ArgList&)
{
return jsUndefined();
}
@@ -63,14 +66,34 @@ CallType FunctionPrototype::getCallData(CallData& callData)
// Functions
-JSValuePtr functionProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.)
+static inline void insertSemicolonIfNeeded(UString& functionBody)
{
- if (thisValue->isObject(&JSFunction::info)) {
+ 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);
- return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + function->body()->toSourceString());
+ 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)) {
+ if (thisValue.isObject(&InternalFunction::info)) {
InternalFunction* function = asInternalFunction(thisValue);
return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n [native code]\n}");
}
@@ -78,59 +101,44 @@ JSValuePtr functionProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr this
return throwError(exec, TypeError);
}
-JSValuePtr functionProtoFuncApply(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
CallData callData;
- CallType callType = thisValue->getCallData(callData);
+ CallType callType = thisValue.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSValuePtr thisArg = args.at(exec, 0);
- JSValuePtr argArray = args.at(exec, 1);
+ JSValue array = args.at(1);
- JSValuePtr applyThis;
- if (thisArg->isUndefinedOrNull())
- applyThis = exec->globalThisValue();
- else
- applyThis = thisArg->toObject(exec);
-
- ArgList applyArgs;
- if (!argArray->isUndefinedOrNull()) {
- if (!argArray->isObject())
+ MarkedArgumentBuffer applyArgs;
+ if (!array.isUndefinedOrNull()) {
+ if (!array.isObject())
return throwError(exec, TypeError);
- if (asObject(argArray)->classInfo() == &Arguments::info)
- asArguments(argArray)->fillArgList(exec, applyArgs);
- else if (exec->interpreter()->isJSArray(argArray))
- asArray(argArray)->fillArgList(exec, applyArgs);
- else if (asObject(argArray)->inherits(&JSArray::info)) {
- unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ 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(argArray)->get(exec, i));
+ applyArgs.append(asArray(array)->get(exec, i));
} else
return throwError(exec, TypeError);
}
- return call(exec, thisValue, callType, callData, applyThis, applyArgs);
+ return call(exec, thisValue, callType, callData, args.at(0), applyArgs);
}
-JSValuePtr functionProtoFuncCall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
CallData callData;
- CallType callType = thisValue->getCallData(callData);
+ CallType callType = thisValue.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSValuePtr thisArg = args.at(exec, 0);
-
- JSObject* callThis;
- if (thisArg->isUndefinedOrNull())
- callThis = exec->globalThisValue();
- else
- callThis = thisArg->toObject(exec);
-
- ArgList argsTail;
- args.getSlice(1, argsTail);
- return call(exec, thisValue, callType, callData, callThis, argsTail);
+ ArgList callArgs;
+ args.getSlice(1, callArgs);
+ return call(exec, thisValue, callType, callData, args.at(0), callArgs);
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h
index 33d68b7..607ddab 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/FunctionPrototype.h
@@ -25,12 +25,14 @@
namespace JSC {
+ class PrototypeFunction;
+
class FunctionPrototype : public InternalFunction {
public:
FunctionPrototype(ExecState*, PassRefPtr<Structure>);
- void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure);
+ void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction);
- static PassRefPtr<Structure> createStructure(JSValuePtr proto)
+ static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.cpp
index d24a024..cd1b40a 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.cpp
@@ -38,17 +38,17 @@ void GetterSetter::mark()
m_setter->mark();
}
-JSValuePtr GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
ASSERT_NOT_REACHED();
return jsNull();
}
-bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
+bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
{
ASSERT_NOT_REACHED();
number = 0;
- value = noValue();
+ value = JSValue();
return true;
}
@@ -73,7 +73,7 @@ UString GetterSetter::toString(ExecState*) const
JSObject* GetterSetter::toObject(ExecState* exec) const
{
ASSERT_NOT_REACHED();
- return jsNull()->toObject(exec);
+ return jsNull().toObject(exec);
}
bool GetterSetter::isGetterSetter() const
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h
index 48e1baf..e6b74a1 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/GetterSetter.h
@@ -50,8 +50,8 @@ namespace JSC {
private:
virtual bool isGetterSetter() const;
- virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& 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;
@@ -61,9 +61,9 @@ namespace JSC {
JSObject* m_setter;
};
- GetterSetter* asGetterSetter(JSValuePtr);
+ GetterSetter* asGetterSetter(JSValue);
- inline GetterSetter* asGetterSetter(JSValuePtr value)
+ inline GetterSetter* asGetterSetter(JSValue value)
{
ASSERT(asCell(value)->isGetterSetter());
return static_cast<GetterSetter*>(asCell(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Identifier.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Identifier.cpp
index 8372010..040c123 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Identifier.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Identifier.cpp
@@ -124,12 +124,12 @@ struct CStringTranslator {
PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
{
if (!c) {
- UString::Rep::null.hash();
- return &UString::Rep::null;
+ UString::Rep::null().hash();
+ return &UString::Rep::null();
}
if (!c[0]) {
- UString::Rep::empty.hash();
- return &UString::Rep::empty;
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
}
if (!c[1])
return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
@@ -194,8 +194,8 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar*
return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
}
if (!length) {
- UString::Rep::empty.hash();
- return &UString::Rep::empty;
+ 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);
@@ -225,8 +225,8 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UStri
}
}
if (!r->len) {
- UString::Rep::empty.hash();
- return &UString::Rep::empty;
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
}
return *globalData->identifierTable->add(r).first;
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/InitializeThreading.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/InitializeThreading.cpp
index a17c386..cda9fb1 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -49,9 +49,9 @@ static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
static void initializeThreadingOnce()
{
WTF::initializeThreading();
+ initializeUString();
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
- UString::null();
initDateMath();
#endif
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.cpp
index 6714cf5..b5c9571 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.cpp
@@ -48,4 +48,24 @@ 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/webkit/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h
index cc4b917..310644c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/InternalFunction.h
@@ -34,11 +34,13 @@ namespace JSC {
class InternalFunction : public JSObject {
public:
virtual const ClassInfo* classInfo() const;
- static const ClassInfo info;
+ static JS_EXPORTDATA const ClassInfo info;
const UString& name(JSGlobalData*);
+ const UString displayName(JSGlobalData*);
+ const UString calculatedDisplayName(JSGlobalData*);
- static PassRefPtr<Structure> createStructure(JSValuePtr proto)
+ static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
}
@@ -51,9 +53,9 @@ namespace JSC {
virtual CallType getCallData(CallData&) = 0;
};
- InternalFunction* asInternalFunction(JSValuePtr);
+ InternalFunction* asInternalFunction(JSValue);
- inline InternalFunction* asInternalFunction(JSValuePtr value)
+ inline InternalFunction* asInternalFunction(JSValue value)
{
ASSERT(asObject(value)->inherits(&InternalFunction::info));
return static_cast<InternalFunction*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.cpp
index d03b3f0..8996629 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.cpp
@@ -75,7 +75,7 @@ void JSActivation::mark()
for ( ; i < count; ++i) {
Register& r = registerArray[i];
- if (!r.marked())
+ if (r.jsValue() && !r.marked())
r.mark();
}
}
@@ -85,7 +85,7 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
if (symbolTableGet(propertyName, slot))
return true;
- if (JSValuePtr* location = getDirectLocation(propertyName)) {
+ if (JSValue* location = getDirectLocation(propertyName)) {
slot.setValueSlot(location);
return true;
}
@@ -99,11 +99,11 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
// 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());
+ ASSERT(prototype().isNull());
return false;
}
-void JSActivation::put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -118,7 +118,7 @@ void JSActivation::put(ExecState*, const Identifier& propertyName, JSValuePtr va
}
// FIXME: Make this function honor ReadOnly (const) and DontEnum
-void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -130,7 +130,7 @@ void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName,
// expose in the activation object.
ASSERT(!hasGetterSetterProperties());
PutPropertySlot slot;
- putDirect(propertyName, value, attributes, true, slot);
+ JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot);
}
bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
@@ -151,7 +151,7 @@ bool JSActivation::isDynamicScope() const
return d()->functionBody->usesEval();
}
-JSValuePtr JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSActivation* activation = asActivation(slot.slotBase());
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h
index 222f423..c183dac 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSActivation.h
@@ -50,11 +50,13 @@ namespace JSC {
virtual bool isDynamicScope() const;
+ virtual bool isActivationObject() const { return true; }
+
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
- virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes);
+ virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual JSObject* toThisObject(ExecState*) const;
@@ -64,7 +66,7 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
private:
struct JSActivationData : public JSVariableObjectData {
@@ -77,15 +79,15 @@ namespace JSC {
RefPtr<FunctionBodyNode> functionBody;
};
- static JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
};
- JSActivation* asActivation(JSValuePtr);
+ JSActivation* asActivation(JSValue);
- inline JSActivation* asActivation(JSValuePtr value)
+ inline JSActivation* asActivation(JSValue value)
{
ASSERT(asObject(value)->inherits(&JSActivation::info));
return static_cast<JSActivation*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp
index 35d0dec..296ac9d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp
@@ -24,9 +24,11 @@
#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
@@ -65,9 +67,9 @@ ASSERT_CLASS_FITS_IN_CELL(JSArray);
// 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(JSValuePtr)) +
-// (vectorLength * sizeof(JSValuePtr)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
-#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr))
+// 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>.
@@ -90,10 +92,10 @@ static inline size_t storageSize(unsigned vectorLength)
// 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(JSValuePtr)) + (vectorLength * sizeof(JSValuePtr));
+ 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(JSValuePtr))) / sizeof(JSValuePtr) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValuePtr))));
+ ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValue))) / sizeof(JSValue) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValue))));
return size;
}
@@ -149,12 +151,12 @@ JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
m_storage->m_vectorLength = initialCapacity;
m_storage->m_length = initialLength;
- Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValuePtr));
+ Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue));
checkConsistency();
}
-JSArray::JSArray(ExecState* exec, PassRefPtr<Structure> structure, const ArgList& list)
+JSArray::JSArray(PassRefPtr<Structure> structure, const ArgList& list)
: JSObject(structure)
{
unsigned length = list.size();
@@ -171,12 +173,11 @@ JSArray::JSArray(ExecState* exec, PassRefPtr<Structure> structure, const ArgList
size_t i = 0;
ArgList::const_iterator end = list.end();
for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
- storage->m_vector[i] = (*it).jsValue(exec);
+ storage->m_vector[i] = *it;
m_storage = storage;
- // When the array is created non-empty, its cells are filled, so it's really no worse than
- // a property map. Therefore don't report extra memory cost.
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(length));
checkConsistency();
}
@@ -200,7 +201,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot
}
if (i < storage->m_vectorLength) {
- JSValuePtr& valueSlot = storage->m_vector[i];
+ JSValue& valueSlot = storage->m_vector[i];
if (valueSlot) {
slot.setValueSlot(&valueSlot);
return true;
@@ -234,7 +235,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName
}
// ECMA 15.4.5.1
-void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(&isArrayIndex);
@@ -244,8 +245,8 @@ void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr va
}
if (propertyName == exec->propertyNames().length) {
- unsigned newLength = value->toUInt32(exec);
- if (value->toNumber(exec) != static_cast<double>(newLength)) {
+ unsigned newLength = value.toUInt32(exec);
+ if (value.toNumber(exec) != static_cast<double>(newLength)) {
throwError(exec, RangeError, "Invalid array length.");
return;
}
@@ -256,7 +257,7 @@ void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr va
JSObject::put(exec, propertyName, value, slot);
}
-void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
+void JSArray::put(ExecState* exec, unsigned i, JSValue value)
{
checkConsistency();
@@ -267,7 +268,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
}
if (i < m_storage->m_vectorLength) {
- JSValuePtr& valueSlot = m_storage->m_vector[i];
+ JSValue& valueSlot = m_storage->m_vector[i];
if (valueSlot) {
valueSlot = value;
checkConsistency();
@@ -283,7 +284,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
putSlowCase(exec, i, value);
}
-NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValuePtr value)
+NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue value)
{
ArrayStorage* storage = m_storage;
SparseArrayValueMap* map = storage->m_sparseValueMap;
@@ -349,14 +350,17 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValuePtr v
}
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] = noValue();
+ 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] = noValue();
+ storage->m_vector[j] = JSValue();
for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
storage->m_vector[j] = map->take(j);
}
@@ -391,12 +395,12 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
ArrayStorage* storage = m_storage;
if (i < storage->m_vectorLength) {
- JSValuePtr& valueSlot = storage->m_vector[i];
+ JSValue& valueSlot = storage->m_vector[i];
if (!valueSlot) {
checkConsistency();
return false;
}
- valueSlot = noValue();
+ valueSlot = JSValue();
--storage->m_numValuesInVector;
if (m_fastAccessCutoff > i)
m_fastAccessCutoff = i;
@@ -462,10 +466,11 @@ bool JSArray::increaseVectorLength(unsigned newLength)
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] = noValue();
+ storage->m_vector[i] = JSValue();
m_storage = storage;
return true;
@@ -485,9 +490,9 @@ void JSArray::setLength(unsigned newLength)
unsigned usedVectorLength = min(length, storage->m_vectorLength);
for (unsigned i = newLength; i < usedVectorLength; ++i) {
- JSValuePtr& valueSlot = storage->m_vector[i];
+ JSValue& valueSlot = storage->m_vector[i];
bool hadValue = valueSlot;
- valueSlot = noValue();
+ valueSlot = JSValue();
storage->m_numValuesInVector -= hadValue;
}
@@ -510,7 +515,7 @@ void JSArray::setLength(unsigned newLength)
checkConsistency();
}
-JSValuePtr JSArray::pop()
+JSValue JSArray::pop()
{
checkConsistency();
@@ -520,19 +525,19 @@ JSValuePtr JSArray::pop()
--length;
- JSValuePtr result;
+ JSValue result;
if (m_fastAccessCutoff > length) {
- JSValuePtr& valueSlot = m_storage->m_vector[length];
+ JSValue& valueSlot = m_storage->m_vector[length];
result = valueSlot;
ASSERT(result);
- valueSlot = noValue();
+ valueSlot = JSValue();
--m_storage->m_numValuesInVector;
m_fastAccessCutoff = length;
} else if (length < m_storage->m_vectorLength) {
- JSValuePtr& valueSlot = m_storage->m_vector[length];
+ JSValue& valueSlot = m_storage->m_vector[length];
result = valueSlot;
- valueSlot = noValue();
+ valueSlot = JSValue();
if (result)
--m_storage->m_numValuesInVector;
else
@@ -559,7 +564,7 @@ JSValuePtr JSArray::pop()
return result;
}
-void JSArray::push(ExecState* exec, JSValuePtr value)
+void JSArray::push(ExecState* exec, JSValue value)
{
checkConsistency();
@@ -599,30 +604,68 @@ void JSArray::mark()
unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
for (unsigned i = 0; i < usedVectorLength; ++i) {
- JSValuePtr value = storage->m_vector[i];
- if (value && !value->marked())
- value->mark();
+ 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) {
- JSValuePtr value = it->second;
- if (!value->marked())
- value->mark();
+ JSValue value = it->second;
+ if (!value.marked())
+ value.mark();
}
}
}
-typedef std::pair<JSValuePtr, UString> ArrayQSortPair;
+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 ArrayQSortPair* va = static_cast<const ArrayQSortPair*>(a);
- const ArrayQSortPair* vb = static_cast<const ArrayQSortPair*>(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();
@@ -639,15 +682,15 @@ void JSArray::sort(ExecState* exec)
// buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
// random or otherwise changing results, effectively making compare function inconsistent.
- Vector<ArrayQSortPair> values(lengthNotIncludingUndefined);
+ Vector<ValueStringPair> values(lengthNotIncludingUndefined);
if (!values.begin()) {
throwOutOfMemoryError(exec);
return;
}
for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
- JSValuePtr value = m_storage->m_vector[i];
- ASSERT(!value->isUndefined());
+ JSValue value = m_storage->m_vector[i];
+ ASSERT(!value.isUndefined());
values[i].first = value;
}
@@ -658,7 +701,7 @@ void JSArray::sort(ExecState* exec)
// a toString call raises an exception.
for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
- values[i].second = values[i].first->toString(exec);
+ values[i].second = values[i].first.toString(exec);
if (exec->hadException())
return;
@@ -667,11 +710,11 @@ void JSArray::sort(ExecState* exec)
// than O(N log N).
#if HAVE(MERGESORT)
- mergesort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
+ 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(ArrayQSortPair), compareByStringPairForQSort);
+ qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
#endif
// FIXME: If the toString function changed the length of the array, this might be
@@ -684,7 +727,7 @@ void JSArray::sort(ExecState* exec)
}
struct AVLTreeNodeForArrayCompare {
- JSValuePtr value;
+ 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
@@ -695,15 +738,16 @@ struct AVLTreeNodeForArrayCompare {
struct AVLTreeAbstractorForArrayCompare {
typedef int32_t handle; // Handle is an index into m_nodes vector.
- typedef JSValuePtr key;
+ typedef JSValue key;
typedef int32_t size;
Vector<AVLTreeNodeForArrayCompare> m_nodes;
ExecState* m_exec;
- JSValuePtr m_compareFunction;
+ JSValue m_compareFunction;
CallType m_compareCallType;
const CallData* m_compareCallData;
- JSValuePtr m_globalThisValue;
+ 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; }
@@ -733,16 +777,24 @@ struct AVLTreeAbstractorForArrayCompare {
int compare_key_key(key va, key vb)
{
- ASSERT(!va->isUndefined());
- ASSERT(!vb->isUndefined());
+ ASSERT(!va.isUndefined());
+ ASSERT(!vb.isUndefined());
if (m_exec->hadException())
return 1;
- ArgList arguments;
- arguments.append(va);
- arguments.append(vb);
- double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments)->toNumber(m_exec);
+ 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.
}
@@ -752,7 +804,7 @@ struct AVLTreeAbstractorForArrayCompare {
static handle null() { return 0x7FFFFFFF; }
};
-void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData)
+void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
{
checkConsistency();
@@ -777,6 +829,9 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
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;
@@ -790,16 +845,16 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValuePtr v = m_storage->m_vector[numDefined];
- if (!v || v->isUndefined())
+ 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) {
- JSValuePtr v = m_storage->m_vector[i];
+ JSValue v = m_storage->m_vector[i];
if (v) {
- if (v->isUndefined())
+ if (v.isUndefined())
++numUndefined;
else {
tree.abstractor().m_nodes[numDefined].value = v;
@@ -851,7 +906,7 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
// Ensure that unused values in the vector are zeroed out.
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- m_storage->m_vector[i] = noValue();
+ m_storage->m_vector[i] = JSValue();
m_fastAccessCutoff = newUsedVectorLength;
m_storage->m_numValuesInVector = newUsedVectorLength;
@@ -859,7 +914,7 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
checkConsistency(SortConsistencyCheck);
}
-void JSArray::fillArgList(ExecState* exec, ArgList& args)
+void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
{
unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff);
unsigned i = 0;
@@ -869,6 +924,19 @@ void JSArray::fillArgList(ExecState* exec, ArgList& args)
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();
@@ -881,14 +949,14 @@ unsigned JSArray::compactForSorting()
unsigned numUndefined = 0;
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValuePtr v = storage->m_vector[numDefined];
- if (!v || v->isUndefined())
+ JSValue v = storage->m_vector[numDefined];
+ if (!v || v.isUndefined())
break;
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- JSValuePtr v = storage->m_vector[i];
+ JSValue v = storage->m_vector[i];
if (v) {
- if (v->isUndefined())
+ if (v.isUndefined())
++numUndefined;
else
storage->m_vector[numDefined++] = v;
@@ -918,7 +986,7 @@ unsigned JSArray::compactForSorting()
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
storage->m_vector[i] = jsUndefined();
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- storage->m_vector[i] = noValue();
+ storage->m_vector[i] = JSValue();
m_fastAccessCutoff = newUsedVectorLength;
storage->m_numValuesInVector = newUsedVectorLength;
@@ -951,7 +1019,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
unsigned numValuesInVector = 0;
for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) {
- if (JSValuePtr value = m_storage->m_vector[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.
@@ -990,16 +1058,16 @@ JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
}
-JSArray* constructArray(ExecState* exec, JSValuePtr singleItemValue)
+JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
{
- ArgList values;
+ MarkedArgumentBuffer values;
values.append(singleItemValue);
- return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
}
JSArray* constructArray(ExecState* exec, const ArgList& values)
{
- return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h
index e280022..ea490d8 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.h
@@ -25,7 +25,7 @@
namespace JSC {
- typedef HashMap<unsigned, JSValuePtr> SparseArrayValueMap;
+ typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
struct ArrayStorage {
unsigned m_length;
@@ -33,7 +33,7 @@ namespace JSC {
unsigned m_numValuesInVector;
SparseArrayValueMap* m_sparseValueMap;
void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
- JSValuePtr m_vector[1];
+ JSValue m_vector[1];
};
class JSArray : public JSObject {
@@ -42,47 +42,49 @@ namespace JSC {
public:
explicit JSArray(PassRefPtr<Structure>);
JSArray(PassRefPtr<Structure>, unsigned initialLength);
- JSArray(ExecState*, PassRefPtr<Structure>, const ArgList& initialValues);
+ 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, JSValuePtr); // FIXME: Make protected and add setItem.
+ virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem.
- static const ClassInfo info;
+ 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*, JSValuePtr compareFunction, CallType, const CallData&);
+ void sort(ExecState*, JSValue compareFunction, CallType, const CallData&);
+ void sortNumeric(ExecState*, JSValue compareFunction, CallType, const CallData&);
- void push(ExecState*, JSValuePtr);
- JSValuePtr pop();
+ void push(ExecState*, JSValue);
+ JSValue pop();
bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; }
- JSValuePtr getIndex(unsigned i)
+ JSValue getIndex(unsigned i)
{
ASSERT(canGetIndex(i));
return m_storage->m_vector[i];
}
bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; }
- JSValuePtr setIndex(unsigned i, JSValuePtr v)
+ JSValue setIndex(unsigned i, JSValue v)
{
ASSERT(canSetIndex(i));
return m_storage->m_vector[i] = v;
}
- void fillArgList(ExecState*, ArgList&);
+ void fillArgList(ExecState*, MarkedArgumentBuffer&);
+ void copyToRegisters(ExecState*, Register*, uint32_t);
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
protected:
- virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -95,7 +97,7 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
- void putSlowCase(ExecState*, unsigned propertyName, JSValuePtr);
+ void putSlowCase(ExecState*, unsigned propertyName, JSValue);
bool increaseVectorLength(unsigned newLength);
@@ -108,19 +110,21 @@ namespace JSC {
ArrayStorage* m_storage;
};
- JSArray* asArray(JSValuePtr);
+ JSArray* asArray(JSValue);
JSArray* constructEmptyArray(ExecState*);
JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
- JSArray* constructArray(ExecState*, JSValuePtr singleItemValue);
+ JSArray* constructArray(ExecState*, JSValue singleItemValue);
JSArray* constructArray(ExecState*, const ArgList& values);
- inline JSArray* asArray(JSValuePtr value)
+ 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/webkit/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp
index 4a19038..2a5e72f 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.cpp
@@ -29,6 +29,8 @@
#include "JSGlobalObject.h"
#include "PropertyNameArray.h"
+using namespace WTF;
+
namespace JSC {
const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", 0, 0, 0 };
@@ -41,7 +43,7 @@ JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteA
putDirect(exec->globalData().propertyNames->length, jsNumber(exec, m_storage->length()), ReadOnly | DontDelete);
}
-PassRefPtr<Structure> JSByteArray::createStructure(JSValuePtr prototype)
+PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
{
PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType));
return result;
@@ -52,7 +54,7 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& property
bool ok;
unsigned index = propertyName.toUInt32(&ok, false);
if (ok && canAccessIndex(index)) {
- slot.setValue(getIndex(index));
+ slot.setValue(getIndex(exec, index));
return true;
}
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
@@ -61,13 +63,13 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& property
bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
if (canAccessIndex(propertyName)) {
- slot.setValue(getIndex(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, JSValuePtr value, PutPropertySlot& slot)
+void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
bool ok;
unsigned index = propertyName.toUInt32(&ok, false);
@@ -78,7 +80,7 @@ void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValuePt
JSObject::put(exec, propertyName, value, slot);
}
-void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
+void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value)
{
setIndex(exec, propertyName, value);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h
index 895200b..57374e0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSByteArray.h
@@ -26,19 +26,20 @@
#ifndef JSByteArray_h
#define JSByteArray_h
-#include "ByteArray.h"
#include "JSObject.h"
+#include <wtf/ByteArray.h>
+
namespace JSC {
class JSByteArray : public JSObject {
- friend class Interpreter;
+ friend class VPtrSet;
public:
bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
- JSValuePtr getIndex(unsigned i)
+ JSValue getIndex(ExecState* exec, unsigned i)
{
ASSERT(canAccessIndex(i));
- return JSImmediate::from(m_storage->data()[i]);
+ return jsNumber(exec, m_storage->data()[i]);
}
void setIndex(unsigned i, int value)
@@ -63,22 +64,22 @@ namespace JSC {
m_storage->data()[i] = static_cast<unsigned char>(value + 0.5);
}
- void setIndex(ExecState* exec, unsigned i, JSValuePtr value)
+ void setIndex(ExecState* exec, unsigned i, JSValue value)
{
- double byteValue = value->toNumber(exec);
+ double byteValue = value.toNumber(exec);
if (exec->hadException())
return;
if (canAccessIndex(i))
setIndex(i, byteValue);
}
- JSByteArray(ExecState* exec, PassRefPtr<Structure>, ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype);
+ 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::JSValuePtr, JSC::PutPropertySlot&);
- virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValuePtr);
+ 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&);
@@ -87,7 +88,7 @@ namespace JSC {
size_t length() const { return m_storage->length(); }
- ByteArray* storage() const { return m_storage.get(); }
+ WTF::ByteArray* storage() const { return m_storage.get(); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
@@ -97,15 +98,18 @@ namespace JSC {
{
}
- RefPtr<ByteArray> m_storage;
+ RefPtr<WTF::ByteArray> m_storage;
const ClassInfo* m_classInfo;
};
- JSByteArray* asByteArray(JSValuePtr value);
- inline JSByteArray* asByteArray(JSValuePtr value)
+ JSByteArray* asByteArray(JSValue value);
+ inline JSByteArray* asByteArray(JSValue value)
{
return static_cast<JSByteArray*>(asCell(value));
}
-}
-#endif
+ 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/webkit/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp
index c1c1ce4..8cf7943 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.cpp
@@ -100,19 +100,6 @@ bool JSCell::getTruncatedUInt32(uint32_t&) const
return false;
}
-bool JSCell::getNumber(double& numericValue) const
-{
- if (!isNumber())
- return false;
- numericValue = static_cast<const JSNumberCell*>(this)->value();
- return true;
-}
-
-double JSCell::getNumber() const
-{
- return isNumber() ? static_cast<const JSNumberCell*>(this)->value() : NaN;
-}
-
bool JSCell::getString(UString&stringValue) const
{
if (!isString())
@@ -170,12 +157,12 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
return true;
}
-void JSCell::put(ExecState* exec, const Identifier& identifier, JSValuePtr value, PutPropertySlot& slot)
+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, JSValuePtr value)
+void JSCell::put(ExecState* exec, unsigned identifier, JSValue value)
{
toObject(exec)->put(exec, identifier, value);
}
@@ -210,9 +197,9 @@ const ClassInfo* JSCell::classInfo() const
return 0;
}
-JSValuePtr JSCell::getJSNumber()
+JSValue JSCell::getJSNumber()
{
- return noValue();
+ return JSValue();
}
bool JSCell::isGetterSetter() const
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h
index 6d963b3..e0a9b4d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSCell.h
@@ -23,6 +23,7 @@
#ifndef JSCell_h
#define JSCell_h
+#include <wtf/Noncopyable.h>
#include "Structure.h"
#include "JSValue.h"
#include "JSImmediate.h"
@@ -30,16 +31,16 @@
namespace JSC {
- class JSCell : public JSValue {
- friend class JIT;
+ class JSCell : Noncopyable {
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 Interpreter;
+ friend class VPtrSet;
private:
explicit JSCell(Structure*);
@@ -56,8 +57,6 @@ namespace JSC {
Structure* structure() const;
// Extracting the value.
- bool getNumber(double&) const;
- double getNumber() const; // NaN if not a number
bool getString(UString&) const;
UString getString() const; // null string if not a string
JSObject* getObject(); // NULL if not an object
@@ -67,13 +66,14 @@ namespace JSC {
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 JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&) = 0;
+ 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;
@@ -88,15 +88,15 @@ namespace JSC {
// Object operations, with the toObject operation included.
virtual const ClassInfo* classInfo() const;
- virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValue);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
virtual JSObject* toThisObject(ExecState*) const;
virtual UString toThisString(ExecState*) const;
virtual JSString* toThisJSString(ExecState*);
- virtual JSValuePtr getJSNumber();
+ virtual JSValue getJSNumber();
void* vptr() { return *reinterpret_cast<void**>(this); }
private:
@@ -108,12 +108,11 @@ namespace JSC {
Structure* m_structure;
};
- JSCell* asCell(JSValuePtr);
+ JSCell* asCell(JSValue);
- inline JSCell* asCell(JSValuePtr value)
+ inline JSCell* asCell(JSValue value)
{
- ASSERT(!JSImmediate::isImmediate(value));
- return value->asCell();
+ return value.asCell();
}
inline JSCell::JSCell(Structure* structure)
@@ -157,8 +156,8 @@ namespace JSC {
ALWAYS_INLINE JSCell* JSValue::asCell() const
{
- ASSERT(!JSImmediate::isImmediate(asValue()));
- return const_cast<JSCell*>(reinterpret_cast<const JSCell*>(this));
+ ASSERT(isCell());
+ return m_ptr;
}
inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
@@ -172,11 +171,6 @@ namespace JSC {
// --- JSValue inlines ----------------------------
- inline bool JSValue::isNumber() const
- {
- return JSImmediate::isNumber(asValue()) || (!JSImmediate::isImmediate(asValue()) && asCell()->isNumber());
- }
-
inline bool JSValue::isString() const
{
return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
@@ -192,11 +186,6 @@ namespace JSC {
return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
}
- inline double JSValue::getNumber() const
- {
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->getNumber();
- }
-
inline bool JSValue::getString(UString& s) const
{
return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
@@ -247,12 +236,12 @@ namespace JSC {
return JSImmediate::isImmediate(asValue()) || asCell()->marked();
}
- inline JSValuePtr JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+ 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, JSValuePtr& value)
+ inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
{
if (JSImmediate::isImmediate(asValue())) {
number = JSImmediate::toDouble(asValue());
@@ -301,9 +290,9 @@ namespace JSC {
return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
}
- inline JSValuePtr JSValue::getJSNumber()
+ inline JSValue JSValue::getJSNumber()
{
- return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();
+ return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? JSValue() : asCell()->getJSNumber();
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.cpp
index a22cb34..f456451 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.cpp
@@ -45,11 +45,29 @@ 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(exec->globalData().nativeFunctionThunk())
+#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)
- , m_scopeChain(scopeChainNode)
{
+ setScopeChain(scopeChainNode);
}
JSFunction::~JSFunction()
@@ -58,55 +76,72 @@ JSFunction::~JSFunction()
// 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();
+ if (!isHostFunction()) {
+ if (m_body && m_body->isGenerated())
+ m_body->generatedBytecode().unlinkCallers();
+ scopeChain().~ScopeChain();
+ }
+
#endif
}
void JSFunction::mark()
{
Base::mark();
- m_body->mark();
- m_scopeChain.mark();
+ if (!isHostFunction()) {
+ m_body->mark();
+ scopeChain().mark();
+ }
}
CallType JSFunction::getCallData(CallData& callData)
{
+ if (isHostFunction()) {
+ callData.native.function = nativeFunction();
+ return CallTypeHost;
+ }
callData.js.functionBody = m_body.get();
- callData.js.scopeChain = m_scopeChain.node();
+ callData.js.scopeChain = scopeChain().node();
return CallTypeJS;
}
-JSValuePtr JSFunction::call(ExecState* exec, JSValuePtr thisValue, const ArgList& args)
+JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args)
{
- return exec->interpreter()->execute(m_body.get(), exec, this, thisValue->toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
+ ASSERT(!isHostFunction());
+ return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
}
-JSValuePtr JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSFunction* thisObj = asFunction(slot.slotBase());
+ ASSERT(!thisObj->isHostFunction());
return exec->interpreter()->retrieveArguments(exec, thisObj);
}
-JSValuePtr JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSFunction* thisObj = asFunction(slot.slotBase());
+ ASSERT(!thisObj->isHostFunction());
return exec->interpreter()->retrieveCaller(exec, thisObj);
}
-JSValuePtr JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+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) {
- JSValuePtr* location = getDirectLocation(propertyName);
+ JSValue* location = getDirectLocation(propertyName);
if (!location) {
- JSObject* prototype = new (exec) JSObject(m_scopeChain.globalObject()->emptyObjectStructure());
+ JSObject* prototype = new (exec) JSObject(scopeChain().globalObject()->emptyObjectStructure());
prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
putDirect(exec->propertyNames().prototype, prototype, DontDelete);
location = getDirectLocation(propertyName);
@@ -133,8 +168,12 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertySlot(exec, propertyName, slot);
}
-void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& 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);
@@ -142,6 +181,8 @@ void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValuePtr
bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
+ if (isHostFunction())
+ return Base::deleteProperty(exec, propertyName);
if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
return false;
return Base::deleteProperty(exec, propertyName);
@@ -150,23 +191,26 @@ bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
// ECMA 13.2.2 [[Construct]]
ConstructType JSFunction::getConstructData(ConstructData& constructData)
{
+ if (isHostFunction())
+ return ConstructTypeNone;
constructData.js.functionBody = m_body.get();
- constructData.js.scopeChain = m_scopeChain.node();
+ constructData.js.scopeChain = scopeChain().node();
return ConstructTypeJS;
}
JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
{
+ ASSERT(!isHostFunction());
Structure* structure;
- JSValuePtr prototype = get(exec, exec->propertyNames().prototype);
- if (prototype->isObject())
+ 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);
- JSValuePtr result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
- if (exec->hadException() || !result->isObject())
+ 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);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h
index 6a43737..b27e515 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSFunction.h
@@ -39,29 +39,30 @@ namespace JSC {
class JSFunction : public InternalFunction {
friend class JIT;
- friend class Interpreter;
+ friend class VPtrSet;
typedef InternalFunction Base;
JSFunction(PassRefPtr<Structure> structure)
: InternalFunction(structure)
- , m_scopeChain(NoScopeChain())
{
+ 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, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
JSObject* construct(ExecState*, const ArgList&);
- JSValuePtr call(ExecState*, JSValuePtr thisValue, const ArgList&);
+ JSValue call(ExecState*, JSValue thisValue, const ArgList&);
- void setScope(const ScopeChain& scopeChain) { m_scopeChain = scopeChain; }
- ScopeChain& scope() { return m_scopeChain; }
+ 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; }
@@ -69,30 +70,64 @@ namespace JSC {
virtual void mark();
- static const ClassInfo info;
+ static JS_EXPORTDATA const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
}
- private:
- virtual const ClassInfo* classInfo() const { return &info; }
+#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&);
- static JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
- static JSValuePtr callerGetter(ExecState*, const Identifier&, const PropertySlot&);
- static JSValuePtr lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
+ 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 m_scopeChain;
+ 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(JSValuePtr);
+ JSFunction* asFunction(JSValue);
- inline JSFunction* asFunction(JSValuePtr value)
+ inline JSFunction* asFunction(JSValue value)
{
ASSERT(asObject(value)->inherits(&JSFunction::info));
return static_cast<JSFunction*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.cpp
index 62df65e..1594848 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -30,15 +30,19 @@
#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 "Interpreter.h"
#include "Parser.h"
-#include "Collector.h"
#include "Lexer.h"
#include "Lookup.h"
#include "Nodes.h"
@@ -63,40 +67,80 @@ extern const HashTable regExpTable;
extern const HashTable regExpConstructorTable;
extern const HashTable stringTable;
-JSGlobalData::JSGlobalData(bool isShared)
- : interpreter(new Interpreter)
- , exception(noValue())
- , arrayTable(new HashTable(JSC::arrayTable))
- , dateTable(new HashTable(JSC::dateTable))
- , mathTable(new HashTable(JSC::mathTable))
- , numberTable(new HashTable(JSC::numberTable))
- , regExpTable(new HashTable(JSC::regExpTable))
- , regExpConstructorTable(new HashTable(JSC::regExpConstructorTable))
- , stringTable(new HashTable(JSC::stringTable))
+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))
+ , 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 ArgList)
- , newParserObjects(0)
- , parserObjectExtraRefCounts(0)
+ , emptyList(new MarkedArgumentBuffer)
, lexer(new Lexer(this))
, parser(new Parser)
+ , interpreter(new Interpreter)
+#if ENABLE(JIT)
+ , jitStubs(this)
+#endif
+ , heap(this)
+ , initializingLazyNumericCompareFunction(false)
, head(0)
, dynamicGlobalObject(0)
- , isSharedInstance(isShared)
- , clientData(0)
- , heap(this)
+ , scopeNodeBeingReparsed(0)
{
#if PLATFORM(MAC)
startProfilerServerIfNeeded();
#endif
- interpreter->initialize(this);
}
JSGlobalData::~JSGlobalData()
@@ -116,13 +160,17 @@ JSGlobalData::~JSGlobalData()
regExpTable->deleteTable();
regExpConstructorTable->deleteTable();
stringTable->deleteTable();
- delete arrayTable;
- delete dateTable;
- delete mathTable;
- delete numberTable;
- delete regExpTable;
- delete regExpConstructorTable;
- delete stringTable;
+#if ENABLE(JIT)
+ lazyNativeFunctionThunk.clear();
+#endif
+
+ fastDelete(const_cast<HashTable*>(arrayTable));
+ fastDelete(const_cast<HashTable*>(dateTable));
+ 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;
@@ -134,27 +182,20 @@ JSGlobalData::~JSGlobalData()
delete propertyNames;
deleteIdentifierTable(identifierTable);
- delete newParserObjects;
- delete parserObjectExtraRefCounts;
-
delete clientData;
}
-PassRefPtr<JSGlobalData> JSGlobalData::create()
+PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared)
{
- return adoptRef(new JSGlobalData);
+ return adoptRef(new JSGlobalData(isShared, VPtrSet()));
}
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
{
-#ifndef NDEBUG
Structure::startIgnoringLeaks();
RefPtr<JSGlobalData> data = create();
Structure::stopIgnoringLeaks();
return data.release();
-#else
- return create();
-#endif
}
bool JSGlobalData::sharedInstanceExists()
@@ -166,7 +207,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
if (!instance) {
- instance = new JSGlobalData(true);
+ instance = create(true).releaseRef();
#if ENABLE(JSC_MULTIPLE_THREADS)
instance->makeUsableFromMultipleThreads();
#endif
@@ -181,8 +222,31 @@ JSGlobalData*& JSGlobalData::sharedInstanceInternal()
return sharedInstance;
}
-JSGlobalData::ClientData::~ClientData()
+#if ENABLE(JIT)
+
+void JSGlobalData::createNativeThunk()
+{
+ lazyNativeFunctionThunk = FunctionBodyNode::createNativeThunk(this);
+}
+
+#endif
+
+// 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/webkit/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h
index 67f4178..e53746b 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalData.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * 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
@@ -29,39 +29,46 @@
#ifndef JSGlobalData_h
#define JSGlobalData_h
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/RefCounted.h>
#include "Collector.h"
#include "ExecutableAllocator.h"
-#include "SmallStrings.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>
struct OpaqueJSClass;
struct OpaqueJSClassContextData;
namespace JSC {
- class ArgList;
class CommonIdentifiers;
- class Heap;
+ class FunctionBodyNode;
class IdentifierTable;
+ class Instruction;
+ class Interpreter;
class JSGlobalObject;
class JSObject;
class Lexer;
- class Interpreter;
class Parser;
- class ParserRefCounted;
+ class ScopeNode;
class Structure;
class UString;
struct HashTable;
+ struct VPtrSet;
class JSGlobalData : public RefCounted<JSGlobalData> {
public:
+ struct ClientData {
+ virtual ~ClientData() = 0;
+ };
+
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
- static PassRefPtr<JSGlobalData> create();
+ static PassRefPtr<JSGlobalData> create(bool isShared = false);
static PassRefPtr<JSGlobalData> createLeaked();
~JSGlobalData();
@@ -70,12 +77,8 @@ namespace JSC {
void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
#endif
- Interpreter* interpreter;
-
- JSValuePtr exception;
-#if ENABLE(JIT)
- void* exceptionLocation;
-#endif
+ bool isSharedInstance;
+ ClientData* clientData;
const HashTable* arrayTable;
const HashTable* dateTable;
@@ -91,48 +94,64 @@ namespace JSC {
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 ArgList* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
-
+ 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;
-
- HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- HashSet<ParserRefCounted*>* newParserObjects;
- HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
+#if ENABLE(ASSEMBLER)
+ ExecutableAllocator executableAllocator;
+#endif
Lexer* lexer;
Parser* parser;
+ Interpreter* interpreter;
+#if ENABLE(JIT)
+ JITThunks jitStubs;
+ FunctionBodyNode* nativeFunctionThunk()
+ {
+ if (!lazyNativeFunctionThunk)
+ createNativeThunk();
+ return lazyNativeFunctionThunk.get();
+ }
+ RefPtr<FunctionBodyNode> lazyNativeFunctionThunk;
+#endif
+ TimeoutChecker timeoutChecker;
+ Heap heap;
- JSGlobalObject* head;
- JSGlobalObject* dynamicGlobalObject;
+ JSValue exception;
+#if ENABLE(JIT)
+ void* exceptionLocation;
+#endif
- bool isSharedInstance;
+ const Vector<Instruction>& numericCompareFunction(ExecState*);
+ Vector<Instruction> lazyNumericCompareFunction;
+ bool initializingLazyNumericCompareFunction;
- struct ClientData {
- virtual ~ClientData() = 0;
- };
+ HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- ClientData* clientData;
+ JSGlobalObject* head;
+ JSGlobalObject* dynamicGlobalObject;
HashSet<JSObject*> arrayVisitedElements;
- Heap heap;
-#if ENABLE(ASSEMBLER)
- PassRefPtr<ExecutablePool> poolForSize(size_t n) { return m_executableAllocator.poolForSize(n); }
-#endif
- private:
- JSGlobalData(bool isShared = false);
-#if ENABLE(ASSEMBLER)
- ExecutableAllocator m_executableAllocator;
-#endif
+ ScopeNode* scopeNodeBeingReparsed;
+ private:
+ JSGlobalData(bool isShared, const VPtrSet&);
static JSGlobalData*& sharedInstanceInternal();
+ void createNativeThunk();
};
-}
+} // namespace JSC
-#endif
+#endif // JSGlobalData_h
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp
index dfe291c..1e9f670 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -47,6 +47,7 @@
#include "FunctionConstructor.h"
#include "FunctionPrototype.h"
#include "GlobalEvalFunction.h"
+#include "JSFunction.h"
#include "JSGlobalObjectFunctions.h"
#include "JSLock.h"
#include "Interpreter.h"
@@ -78,10 +79,10 @@ static const int initialTickCountThreshold = 255;
// Preferred number of milliseconds between each timeout check
static const int preferredScriptCheckTimeInterval = 1000;
-static inline void markIfNeeded(JSValuePtr v)
+static inline void markIfNeeded(JSValue v)
{
- if (v && !v->marked())
- v->mark();
+ if (v && !v.marked())
+ v.mark();
}
static inline void markIfNeeded(const RefPtr<Structure>& s)
@@ -147,7 +148,7 @@ void JSGlobalObject::init(JSObject* thisValue)
reset(prototype());
}
-void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -156,20 +157,20 @@ void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValu
JSVariableObject::put(exec, propertyName, value, slot);
}
-void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+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;
- JSValuePtr valueBefore = getDirect(propertyName);
+ JSValue valueBefore = getDirect(propertyName);
PutPropertySlot slot;
JSVariableObject::put(exec, propertyName, value, slot);
if (!valueBefore) {
- JSValuePtr valueAfter = getDirect(propertyName);
+ JSValue valueAfter = getDirect(propertyName);
if (valueAfter)
- putDirect(propertyName, valueAfter, attributes);
+ JSObject::putWithAttributes(exec, propertyName, valueAfter, attributes);
}
}
@@ -190,12 +191,12 @@ void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyNam
static inline JSObject* lastInPrototypeChain(JSObject* object)
{
JSObject* o = object;
- while (o->prototype()->isObject())
+ while (o->prototype().isObject())
o = asObject(o->prototype());
return o;
}
-void JSGlobalObject::reset(JSValuePtr prototype)
+void JSGlobalObject::reset(JSValue prototype)
{
ExecState* exec = JSGlobalObject::globalExec();
@@ -203,7 +204,11 @@ void JSGlobalObject::reset(JSValuePtr prototype)
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);
- d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get());
+ 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);
@@ -234,6 +239,8 @@ void JSGlobalObject::reset(JSValuePtr prototype)
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);
@@ -248,13 +255,13 @@ void JSGlobalObject::reset(JSValuePtr prototype)
// Constructors
- JSValuePtr objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
- JSValuePtr functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
- JSValuePtr arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
- JSValuePtr stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
- JSValuePtr booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
- JSValuePtr numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
- JSValuePtr dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
+ 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);
@@ -269,15 +276,15 @@ void JSGlobalObject::reset(JSValuePtr prototype)
d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
- d()->objectPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
- d()->functionPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
- d()->arrayPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
- d()->booleanPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
- d()->stringPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
- d()->numberPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
- d()->datePrototype->putDirectWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
- d()->regExpPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
- errorPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
+ 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);
@@ -290,21 +297,21 @@ void JSGlobalObject::reset(JSValuePtr prototype)
// FIXME: These properties could be handled by a static hash table.
- putDirectWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
- putDirectWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
- putDirectWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
- putDirectWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
- putDirectWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
- putDirectWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
- putDirectWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);
+ 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);
+ putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
+ putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
+ putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
+ putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
+ putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
@@ -320,43 +327,32 @@ void JSGlobalObject::reset(JSValuePtr prototype)
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) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+ 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
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
#endif
resetPrototype(prototype);
}
// Set prototype, and also insert the object prototype at the end of the chain.
-void JSGlobalObject::resetPrototype(JSValuePtr prototype)
+void JSGlobalObject::resetPrototype(JSValue prototype)
{
setPrototype(prototype);
- lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
-}
-
-void JSGlobalObject::setTimeoutTime(unsigned timeoutTime)
-{
- globalData()->interpreter->setTimeoutTime(timeoutTime);
-}
-void JSGlobalObject::startTimeoutCheck()
-{
- globalData()->interpreter->startTimeoutCheck();
-}
-
-void JSGlobalObject::stopTimeoutCheck()
-{
- globalData()->interpreter->stopTimeoutCheck();
+ JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
+ JSObject* objectPrototype = d()->objectPrototype;
+ if (oldLastInPrototypeChain != objectPrototype)
+ oldLastInPrototypeChain->setPrototype(objectPrototype);
}
void JSGlobalObject::mark()
@@ -381,6 +377,8 @@ void JSGlobalObject::mark()
markIfNeeded(d()->URIErrorConstructor);
markIfNeeded(d()->evalFunction);
+ markIfNeeded(d()->callFunction);
+ markIfNeeded(d()->applyFunction);
markIfNeeded(d()->objectPrototype);
markIfNeeded(d()->functionPrototype);
@@ -391,6 +389,8 @@ void JSGlobalObject::mark()
markIfNeeded(d()->datePrototype);
markIfNeeded(d()->regExpPrototype);
+ markIfNeeded(d()->methodCallDummy);
+
markIfNeeded(d()->errorStructure);
// No need to mark the other structures, because their prototypes are all
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h
index 4a10f64..da9a819 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObject.h
@@ -24,6 +24,7 @@
#include "JSGlobalData.h"
#include "JSVariableObject.h"
+#include "NativeFunctionWrapper.h"
#include "NumberPrototype.h"
#include "StringPrototype.h"
#include <wtf/HashSet.h>
@@ -40,6 +41,7 @@ namespace JSC {
class GlobalEvalFunction;
class NativeErrorConstructor;
class ProgramCodeBlock;
+ class PrototypeFunction;
class RegExpConstructor;
class RegExpPrototype;
class RegisterFile;
@@ -67,6 +69,8 @@ namespace JSC {
, typeErrorConstructor(0)
, URIErrorConstructor(0)
, evalFunction(0)
+ , callFunction(0)
+ , applyFunction(0)
, objectPrototype(0)
, functionPrototype(0)
, arrayPrototype(0)
@@ -75,6 +79,7 @@ namespace JSC {
, numberPrototype(0)
, datePrototype(0)
, regExpPrototype(0)
+ , methodCallDummy(0)
{
}
@@ -104,6 +109,8 @@ namespace JSC {
NativeErrorConstructor* URIErrorConstructor;
GlobalEvalFunction* evalFunction;
+ NativeFunctionWrapper* callFunction;
+ NativeFunctionWrapper* applyFunction;
ObjectPrototype* objectPrototype;
FunctionPrototype* functionPrototype;
@@ -114,6 +121,8 @@ namespace JSC {
DatePrototype* datePrototype;
RegExpPrototype* regExpPrototype;
+ JSObject* methodCallDummy;
+
RefPtr<Structure> argumentsStructure;
RefPtr<Structure> arrayStructure;
RefPtr<Structure> booleanObjectStructure;
@@ -161,8 +170,8 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
- virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
- virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes);
+ 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);
@@ -195,6 +204,8 @@ namespace JSC {
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(); }
@@ -214,10 +225,6 @@ namespace JSC {
void setProfileGroup(unsigned value) { d()->profileGroup = value; }
unsigned profileGroup() const { return d()->profileGroup; }
- void setTimeoutTime(unsigned timeoutTime);
- void startTimeoutCheck();
- void stopTimeoutCheck();
-
Debugger* debugger() const { return d()->debugger; }
void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
@@ -244,19 +251,19 @@ namespace JSC {
void copyGlobalsFrom(RegisterFile&);
void copyGlobalsTo(RegisterFile&);
- void resetPrototype(JSValuePtr prototype);
+ void resetPrototype(JSValue prototype);
JSGlobalData* globalData() { return d()->globalData.get(); }
JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
protected:
struct GlobalPropertyInfo {
- GlobalPropertyInfo(const Identifier& i, JSValuePtr v, unsigned a)
+ GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
: identifier(i)
, value(v)
, attributes(a)
@@ -264,7 +271,7 @@ namespace JSC {
}
const Identifier identifier;
- JSValuePtr value;
+ JSValue value;
unsigned attributes;
};
void addStaticGlobals(GlobalPropertyInfo*, int count);
@@ -272,16 +279,16 @@ namespace JSC {
private:
// FIXME: Fold reset into init.
void init(JSObject* thisValue);
- void reset(JSValuePtr prototype);
+ 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(JSValuePtr);
+ JSGlobalObject* asGlobalObject(JSValue);
- inline JSGlobalObject* asGlobalObject(JSValuePtr value)
+ inline JSGlobalObject* asGlobalObject(JSValue value)
{
ASSERT(asObject(value)->isGlobalObject());
return static_cast<JSGlobalObject*>(asObject(value));
@@ -333,7 +340,7 @@ namespace JSC {
return asGlobalObject(n->object);
}
- inline JSValuePtr Structure::prototypeForLookup(ExecState* exec)
+ inline JSValue Structure::prototypeForLookup(ExecState* exec) const
{
if (typeInfo().type() == ObjectType)
return m_prototype;
@@ -345,6 +352,32 @@ namespace JSC {
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())
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index ecdddcf..b013957 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -28,6 +28,7 @@
#include "CallFrame.h"
#include "GlobalEvalFunction.h"
#include "JSGlobalObject.h"
+#include "LiteralParser.h"
#include "JSString.h"
#include "Interpreter.h"
#include "Parser.h"
@@ -47,9 +48,9 @@ using namespace Unicode;
namespace JSC {
-static JSValuePtr encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
+static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
{
- UString str = args.at(exec, 0)->toString(exec);
+ 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.");
@@ -69,10 +70,10 @@ static JSValuePtr encode(ExecState* exec, const ArgList& args, const char* doNot
return jsString(exec, result);
}
-static JSValuePtr decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
+static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
{
UString result = "";
- UString str = args.at(exec, 0)->toString(exec);
+ UString str = args.at(0).toString(exec);
int k = 0;
int len = str.size();
const UChar* d = str.data();
@@ -268,18 +269,22 @@ static double parseFloat(const UString& s)
return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
}
-JSValuePtr globalFuncEval(ExecState* exec, JSObject* function, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObject = thisValue->toThisObject(exec);
+ 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");
- JSValuePtr x = args.at(exec, 0);
- if (!x->isString())
+ JSValue x = args.at(0);
+ if (!x.isString())
return x;
- UString s = x->toString(exec);
+ UString s = x.toString(exec);
+
+ LiteralParser preparser(exec, s);
+ if (JSValue parsedObject = preparser.tryLiteralParse())
+ return parsedObject;
int errLine;
UString errMsg;
@@ -293,42 +298,42 @@ JSValuePtr globalFuncEval(ExecState* exec, JSObject* function, JSValuePtr thisVa
return exec->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
}
-JSValuePtr globalFuncParseInt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- JSValuePtr value = args.at(exec, 0);
- int32_t radix = args.at(exec, 1)->toInt32(exec);
+ JSValue value = args.at(0);
+ int32_t radix = args.at(1).toInt32(exec);
- if (value->isNumber() && (radix == 0 || radix == 10)) {
- if (JSImmediate::isImmediate(value))
+ if (value.isNumber() && (radix == 0 || radix == 10)) {
+ if (value.isInt32Fast())
return value;
- double d = value->uncheckedGetNumber();
+ double d = value.uncheckedGetNumber();
if (isfinite(d))
- return jsNumber(exec, floor(d));
+ return jsNumber(exec, (d > 0) ? floor(d) : ceil(d));
if (isnan(d) || isinf(d))
return jsNaN(&exec->globalData());
- return JSImmediate::zeroImmediate();
+ return jsNumber(exec, 0);
}
- return jsNumber(exec, parseInt(value->toString(exec), radix));
+ return jsNumber(exec, parseInt(value.toString(exec), radix));
}
-JSValuePtr globalFuncParseFloat(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, parseFloat(args.at(exec, 0)->toString(exec)));
+ return jsNumber(exec, parseFloat(args.at(0).toString(exec)));
}
-JSValuePtr globalFuncIsNaN(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsBoolean(isnan(args.at(exec, 0)->toNumber(exec)));
+ return jsBoolean(isnan(args.at(0).toNumber(exec)));
}
-JSValuePtr globalFuncIsFinite(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- double n = args.at(exec, 0)->toNumber(exec);
+ double n = args.at(0).toNumber(exec);
return jsBoolean(!isnan(n) && !isinf(n));
}
-JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
static const char do_not_unescape_when_decoding_URI[] =
"#$&+,/:;=?@";
@@ -336,12 +341,12 @@ JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const Arg
return decode(exec, args, do_not_unescape_when_decoding_URI, true);
}
-JSValuePtr globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
return decode(exec, args, "", true);
}
-JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
static const char do_not_escape_when_encoding_URI[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -352,7 +357,7 @@ JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const Arg
return encode(exec, args, do_not_escape_when_encoding_URI);
}
-JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
static const char do_not_escape_when_encoding_URI_component[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -363,7 +368,7 @@ JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr,
return encode(exec, args, do_not_escape_when_encoding_URI_component);
}
-JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
static const char do_not_escape[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -373,7 +378,7 @@ JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
UString result = "";
UString s;
- UString str = args.at(exec, 0)->toString(exec);
+ 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];
@@ -394,22 +399,22 @@ JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
return jsString(exec, result);
}
-JSValuePtr globalFuncUnescape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
UString result = "";
- UString str = args.at(exec, 0)->toString(exec);
+ 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 (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
+ 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 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
+ } 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;
@@ -422,10 +427,10 @@ JSValuePtr globalFuncUnescape(ExecState* exec, JSObject*, JSValuePtr, const ArgL
}
#ifndef NDEBUG
-JSValuePtr globalFuncJSCPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
CStringBuffer string;
- args.at(exec, 0)->toString(exec).getCString(string);
+ args.at(0).toString(exec).getCString(string);
puts(string.data());
return jsUndefined();
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
index ea1f106..b1046f2 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
@@ -24,34 +24,36 @@
#ifndef JSGlobalObjectFunctions_h
#define JSGlobalObjectFunctions_h
-#include "JSImmediate.h" // temporary until JSValue* becomes a class we can forward-declare
+#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.
- JSValuePtr globalFuncEval(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncParseInt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncParseFloat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncIsNaN(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncIsFinite(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncDecodeURI(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncEncodeURI(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncEscape(ExecState*, JSObject*, JSValuePtr, const ArgList&);
- JSValuePtr globalFuncUnescape(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ 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
- JSValuePtr globalFuncJSCPrint(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ 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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.cpp
index 09b3750..201e56c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.cpp
@@ -32,35 +32,31 @@
namespace JSC {
-JSObject* JSImmediate::toThisObject(JSValuePtr v, ExecState* exec)
+JSObject* JSImmediate::toThisObject(JSValue v, ExecState* exec)
{
ASSERT(isImmediate(v));
if (isNumber(v))
- return constructNumberFromImmediateNumber(exec, v);
+ return constructNumber(exec, v);
if (isBoolean(v))
return constructBooleanFromImmediateBoolean(exec, v);
- if (v->isNull())
- return exec->globalThisValue();
-
- JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
- exec->setException(exception);
- return new (exec) JSNotAnObject(exec, exception);
+ ASSERT(v.isUndefinedOrNull());
+ return exec->globalThisValue();
}
-JSObject* JSImmediate::toObject(JSValuePtr v, ExecState* exec)
+JSObject* JSImmediate::toObject(JSValue v, ExecState* exec)
{
ASSERT(isImmediate(v));
if (isNumber(v))
- return constructNumberFromImmediateNumber(exec, v);
+ return constructNumber(exec, v);
if (isBoolean(v))
return constructBooleanFromImmediateBoolean(exec, v);
- JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
exec->setException(exception);
return new (exec) JSNotAnObject(exec, exception);
}
-JSObject* JSImmediate::prototype(JSValuePtr v, ExecState* exec)
+JSObject* JSImmediate::prototype(JSValue v, ExecState* exec)
{
ASSERT(isImmediate(v));
if (isNumber(v))
@@ -68,23 +64,34 @@ JSObject* JSImmediate::prototype(JSValuePtr v, ExecState* exec)
if (isBoolean(v))
return exec->lexicalGlobalObject()->booleanPrototype();
- JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
exec->setException(exception);
return new (exec) JSNotAnObject(exec, exception);
}
-UString JSImmediate::toString(JSValuePtr v)
+UString JSImmediate::toString(JSValue v)
{
ASSERT(isImmediate(v));
- if (isNumber(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())
+ if (v.isNull())
return "null";
- ASSERT(v->isUndefined());
+ ASSERT(v.isUndefined());
return "undefined";
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.h
index 37bca2a..706396e 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSImmediate.h
@@ -25,6 +25,7 @@
#include <wtf/Assertions.h>
#include <wtf/AlwaysInline.h>
#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
#include "JSValue.h"
#include <limits>
#include <limits.h>
@@ -36,10 +37,23 @@ namespace JSC {
class ExecState;
class JSCell;
+ class JSFastMath;
+ class JSGlobalData;
class JSObject;
- class JSValue;
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
@@ -84,14 +98,33 @@ namespace JSC {
/*
* On 64-bit platforms, we support an alternative encoding form for immediates, if
- * USE(ALTERNATE_JSIMMEDIATE) is defined.
+ * 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 top 16-bits denote the type:
+ * 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'
+ * 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.
*/
@@ -99,14 +132,41 @@ namespace JSC {
class JSImmediate {
private:
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)
- static const intptr_t TagTypeInteger = 0xffff000000000000ll; // bottom bit set indicates integer, this dominates the following bit
+ // 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 TagTypeInteger = 0x1; // bottom bit set indicates integer, this dominates the following bit
+ 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 = TagTypeInteger | TagBitTypeOther;
+ 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;
@@ -128,157 +188,102 @@ namespace JSC {
static const int32_t signBit = 0x80000000;
- public:
- static ALWAYS_INLINE bool isImmediate(JSValuePtr v)
+ static ALWAYS_INLINE bool isImmediate(JSValue v)
{
return rawValue(v) & TagMask;
}
- static ALWAYS_INLINE bool isNumber(JSValuePtr v)
+ 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 rawValue(v) & TagTypeInteger;
+ return isNumber(v) && !isIntegerNumber(v);
}
+#endif
- static ALWAYS_INLINE bool isPositiveNumber(JSValuePtr v)
+ 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 | TagTypeInteger)) == TagTypeInteger;
+ return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber;
}
- static ALWAYS_INLINE bool isBoolean(JSValuePtr v)
+ static ALWAYS_INLINE bool isBoolean(JSValue v)
{
return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool;
}
- static ALWAYS_INLINE bool isUndefinedOrNull(JSValuePtr v)
+ static ALWAYS_INLINE bool isUndefinedOrNull(JSValue v)
{
// Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
}
- static bool isNegative(JSValuePtr v)
- {
- ASSERT(isNumber(v));
- return rawValue(v) & signBit;
- }
-
- static JSValuePtr from(char);
- static JSValuePtr from(signed char);
- static JSValuePtr from(unsigned char);
- static JSValuePtr from(short);
- static JSValuePtr from(unsigned short);
- static JSValuePtr from(int);
- static JSValuePtr from(unsigned);
- static JSValuePtr from(long);
- static JSValuePtr from(unsigned long);
- static JSValuePtr from(long long);
- static JSValuePtr from(unsigned long long);
- static JSValuePtr from(double);
-
- static ALWAYS_INLINE bool isEitherImmediate(JSValuePtr v1, JSValuePtr v2)
+ static JSValue from(char);
+ static JSValue from(signed char);
+ static JSValue from(unsigned char);
+ static JSValue from(short);
+ static JSValue from(unsigned short);
+ static JSValue from(int);
+ static JSValue from(unsigned);
+ static JSValue from(long);
+ static JSValue from(unsigned long);
+ static JSValue from(long long);
+ static JSValue from(unsigned long long);
+ static JSValue from(double);
+
+ static ALWAYS_INLINE bool isEitherImmediate(JSValue v1, JSValue v2)
{
return (rawValue(v1) | rawValue(v2)) & TagMask;
}
- static ALWAYS_INLINE bool isAnyImmediate(JSValuePtr v1, JSValuePtr v2, JSValuePtr v3)
- {
- return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask;
- }
-
- static ALWAYS_INLINE bool areBothImmediate(JSValuePtr v1, JSValuePtr v2)
+ static ALWAYS_INLINE bool areBothImmediate(JSValue v1, JSValue v2)
{
return isImmediate(v1) & isImmediate(v2);
}
- static ALWAYS_INLINE bool areBothImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
- {
- return rawValue(v1) & rawValue(v2) & TagTypeInteger;
- }
-
- static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(areBothImmediateNumbers(v1, v2));
- return makeValue(rawValue(v1) & rawValue(v2));
- }
-
- static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(areBothImmediateNumbers(v1, v2));
- return makeValue((rawValue(v1) ^ rawValue(v2)) | TagTypeInteger);
- }
-
- static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(areBothImmediateNumbers(v1, v2));
- return makeValue(rawValue(v1) | rawValue(v2));
- }
-
- static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift)
+ static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
{
- ASSERT(areBothImmediateNumbers(val, shift));
#if USE(ALTERNATE_JSIMMEDIATE)
- return makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f))) | TagTypeInteger);
+ return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
#else
- return makeValue((rawValue(val) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagTypeInteger);
+ return rawValue(v1) & rawValue(v2) & TagTypeNumber;
#endif
}
- static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v)
- {
- // Number is non-negative and an operation involving two of these can't overflow.
- // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
- return (rawValue(v) & (TagTypeInteger + (signBit | (signBit >> 1)))) == TagTypeInteger;
- }
-
- static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(canDoFastAdditiveOperations(v1));
- ASSERT(canDoFastAdditiveOperations(v2));
- return makeValue(rawValue(v1) + rawValue(v2) - TagTypeInteger);
- }
-
- static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(canDoFastAdditiveOperations(v1));
- ASSERT(canDoFastAdditiveOperations(v2));
- return makeValue(rawValue(v1) - rawValue(v2) + TagTypeInteger);
- }
-
- static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v)
- {
- ASSERT(canDoFastAdditiveOperations(v));
- return makeValue(rawValue(v) + (1 << IntegerPayloadShift));
- }
-
- static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v)
- {
- ASSERT(canDoFastAdditiveOperations(v));
- return makeValue(rawValue(v) - (1 << IntegerPayloadShift));
- }
-
- static double toDouble(JSValuePtr);
- static bool toBoolean(JSValuePtr);
- static JSObject* toObject(JSValuePtr, ExecState*);
- static JSObject* toThisObject(JSValuePtr, ExecState*);
- static UString toString(JSValuePtr);
+ 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(JSValuePtr, uint32_t&);
- static bool getTruncatedInt32(JSValuePtr, int32_t&);
- static bool getTruncatedUInt32(JSValuePtr, uint32_t&);
+ static bool getUInt32(JSValue, uint32_t&);
+ static bool getTruncatedInt32(JSValue, int32_t&);
+ static bool getTruncatedUInt32(JSValue, uint32_t&);
- static int32_t getTruncatedInt32(JSValuePtr);
- static uint32_t getTruncatedUInt32(JSValuePtr);
+ static int32_t getTruncatedInt32(JSValue);
+ static uint32_t getTruncatedUInt32(JSValue);
- static JSValuePtr trueImmediate();
- static JSValuePtr falseImmediate();
- static JSValuePtr undefinedImmediate();
- static JSValuePtr nullImmediate();
- static JSValuePtr zeroImmediate();
- static JSValuePtr oneImmediate();
+ static JSValue trueImmediate();
+ static JSValue falseImmediate();
+ static JSValue undefinedImmediate();
+ static JSValue nullImmediate();
+ static JSValue zeroImmediate();
+ static JSValue oneImmediate();
- static JSValuePtr impossibleValue();
-
- static JSObject* prototype(JSValuePtr, ExecState*);
+ static JSObject* prototype(JSValue, ExecState*);
private:
#if USE(ALTERNATE_JSIMMEDIATE)
@@ -290,51 +295,71 @@ namespace JSC {
#endif
static const unsigned maxImmediateUInt = maxImmediateInt;
- static ALWAYS_INLINE JSValuePtr makeValue(intptr_t integer)
+ static ALWAYS_INLINE JSValue makeValue(intptr_t integer)
{
- return JSValuePtr::makeImmediate(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 JSValuePtr makeInt(uint32_t value)
+ static ALWAYS_INLINE JSValue makeInt(uint32_t value)
#else
- static ALWAYS_INLINE JSValuePtr makeInt(int32_t value)
+ static ALWAYS_INLINE JSValue makeInt(int32_t value)
#endif
{
- return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeInteger);
+ 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 JSValuePtr makeBool(bool b)
+ static ALWAYS_INLINE JSValue makeBool(bool b)
{
return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
}
- static ALWAYS_INLINE JSValuePtr makeUndefined()
+ static ALWAYS_INLINE JSValue makeUndefined()
{
return makeValue(FullTagTypeUndefined);
}
- static ALWAYS_INLINE JSValuePtr makeNull()
+ static ALWAYS_INLINE JSValue makeNull()
{
return makeValue(FullTagTypeNull);
}
-
- static ALWAYS_INLINE int32_t intValue(JSValuePtr v)
+
+ 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(JSValuePtr v)
+ static ALWAYS_INLINE uint32_t uintValue(JSValue v)
{
return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift);
}
- static ALWAYS_INLINE bool boolValue(JSValuePtr v)
+ static ALWAYS_INLINE bool boolValue(JSValue v)
{
return rawValue(v) & ExtendedPayloadBitBoolValue;
}
- static ALWAYS_INLINE intptr_t rawValue(JSValuePtr v)
+ static ALWAYS_INLINE intptr_t rawValue(JSValue v)
{
return v.immediateValue();
}
@@ -342,177 +367,204 @@ namespace JSC {
static double nonInlineNaN();
};
- ALWAYS_INLINE JSValuePtr JSImmediate::trueImmediate() { return makeBool(true); }
- ALWAYS_INLINE JSValuePtr JSImmediate::falseImmediate() { return makeBool(false); }
- ALWAYS_INLINE JSValuePtr JSImmediate::undefinedImmediate() { return makeUndefined(); }
- ALWAYS_INLINE JSValuePtr JSImmediate::nullImmediate() { return makeNull(); }
- ALWAYS_INLINE JSValuePtr JSImmediate::zeroImmediate() { return makeInt(0); }
- ALWAYS_INLINE JSValuePtr JSImmediate::oneImmediate() { return makeInt(1); }
+ ALWAYS_INLINE JSValue JSImmediate::trueImmediate() { return makeBool(true); }
+ ALWAYS_INLINE JSValue JSImmediate::falseImmediate() { return makeBool(false); }
+ ALWAYS_INLINE JSValue JSImmediate::undefinedImmediate() { return makeUndefined(); }
+ ALWAYS_INLINE JSValue JSImmediate::nullImmediate() { return makeNull(); }
+ ALWAYS_INLINE JSValue JSImmediate::zeroImmediate() { return makeInt(0); }
+ ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); }
- // This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate
- ALWAYS_INLINE JSValuePtr JSImmediate::impossibleValue() { return makeValue(0x4); }
+#if USE(ALTERNATE_JSIMMEDIATE)
+ inline bool doubleToBoolean(double value)
+ {
+ return value < 0.0 || value > 0.0;
+ }
- ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v)
+ 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));
- intptr_t bits = rawValue(v);
- return (bits & TagTypeInteger)
- ? bits != TagTypeInteger // !0 ints
- : bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue); // bool true
+ return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate();
}
+#endif
- ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValuePtr v)
+ ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
{
- ASSERT(isNumber(v));
+ // FIXME: should probably be asserting isPositiveIntegerNumber here.
+ ASSERT(isIntegerNumber(v));
return intValue(v);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(char i)
+#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 JSValuePtr JSImmediate::from(signed char i)
+ ALWAYS_INLINE JSValue JSImmediate::from(signed char i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned char i)
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned char i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(short i)
+ ALWAYS_INLINE JSValue JSImmediate::from(short i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned short i)
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned short i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(int i)
+ ALWAYS_INLINE JSValue JSImmediate::from(int i)
{
+#if !USE(ALTERNATE_JSIMMEDIATE)
if ((i < minImmediateInt) | (i > maxImmediateInt))
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
+#endif
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned i)
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned i)
{
if (i > maxImmediateUInt)
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(long i)
+ ALWAYS_INLINE JSValue JSImmediate::from(long i)
{
if ((i < minImmediateInt) | (i > maxImmediateInt))
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long i)
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned long i)
{
if (i > maxImmediateUInt)
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(i);
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(long long i)
+ ALWAYS_INLINE JSValue JSImmediate::from(long long i)
{
if ((i < minImmediateInt) | (i > maxImmediateInt))
- return noValue();
+ return JSValue();
return makeInt(static_cast<intptr_t>(i));
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long long i)
+ ALWAYS_INLINE JSValue JSImmediate::from(unsigned long long i)
{
if (i > maxImmediateUInt)
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(static_cast<intptr_t>(i));
}
- ALWAYS_INLINE JSValuePtr JSImmediate::from(double d)
+ ALWAYS_INLINE JSValue JSImmediate::from(double d)
{
const int intVal = static_cast<int>(d);
- if ((intVal < minImmediateInt) | (intVal > maxImmediateInt))
- return noValue();
-
// Check for data loss from conversion to int.
if (intVal != d || (!intVal && signbit(d)))
- return noValue();
+ return fromNumberOutsideIntegerRange(d);
- return makeInt(intVal);
+ return from(intVal);
}
- ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValuePtr v)
+ ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue v)
{
- ASSERT(isNumber(v));
+ ASSERT(isIntegerNumber(v));
return intValue(v);
}
- ALWAYS_INLINE double JSImmediate::toDouble(JSValuePtr v)
+ ALWAYS_INLINE double JSImmediate::toDouble(JSValue v)
{
ASSERT(isImmediate(v));
- int i;
- if (isNumber(v))
- i = intValue(v);
- else if (rawValue(v) == FullTagTypeUndefined)
+
+ 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();
- else
- i = rawValue(v) >> ExtendedPayloadShift;
- return i;
+
+ ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate()));
+ return rawValue(v) >> ExtendedPayloadShift;
}
- ALWAYS_INLINE bool JSImmediate::getUInt32(JSValuePtr v, uint32_t& i)
+ ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue v, uint32_t& i)
{
i = uintValue(v);
- return isPositiveNumber(v);
+ return isPositiveIntegerNumber(v);
}
- ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValuePtr v, int32_t& i)
+ ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue v, int32_t& i)
{
i = intValue(v);
- return isNumber(v);
+ return isIntegerNumber(v);
}
- ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValuePtr v, uint32_t& i)
+ ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue v, uint32_t& i)
{
return getUInt32(v, i);
}
- inline JSValuePtr jsNull()
- {
- return JSImmediate::nullImmediate();
- }
+ // 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 JSValuePtr jsBoolean(bool b)
+ inline JSValue::JSValue(JSNullTag)
{
- return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
+ *this = JSImmediate::nullImmediate();
}
-
- inline JSValuePtr jsUndefined()
+
+ inline JSValue::JSValue(JSUndefinedTag)
{
- return JSImmediate::undefinedImmediate();
+ *this = JSImmediate::undefinedImmediate();
}
- // 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 bool JSValue::isUndefined() const
+ inline JSValue::JSValue(JSTrueTag)
{
- return asValue() == jsUndefined();
+ *this = JSImmediate::trueImmediate();
}
- inline bool JSValue::isNull() const
+ inline JSValue::JSValue(JSFalseTag)
{
- return asValue() == jsNull();
+ *this = JSImmediate::falseImmediate();
}
inline bool JSValue::isUndefinedOrNull() const
@@ -545,8 +597,8 @@ namespace JSC {
int32_t i;
if (getTruncatedInt32(i))
return i;
- bool ok;
- return toInt32SlowCase(exec, ok);
+ bool ignored;
+ return toInt32SlowCase(toNumber(exec), ignored);
}
inline uint32_t JSValue::toUInt32(ExecState* exec) const
@@ -554,8 +606,8 @@ namespace JSC {
uint32_t i;
if (getTruncatedUInt32(i))
return i;
- bool ok;
- return toUInt32SlowCase(exec, ok);
+ bool ignored;
+ return toUInt32SlowCase(toNumber(exec), ignored);
}
inline int32_t toInt32(double val)
@@ -583,7 +635,7 @@ namespace JSC {
ok = true;
return i;
}
- return toInt32SlowCase(exec, ok);
+ return toInt32SlowCase(toNumber(exec), ok);
}
inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
@@ -593,9 +645,142 @@ namespace JSC {
ok = true;
return i;
}
- return toUInt32SlowCase(exec, ok);
+ 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/webkit/JavaScriptCore/runtime/JSLock.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSLock.cpp
index 5662a41..7ece5da 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSLock.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSLock.cpp
@@ -119,11 +119,58 @@ bool JSLock::currentThreadIsHoldingLock()
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_lockingForReal(exec->globalData().isSharedInstance)
{
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_lockingForReal);
@@ -134,6 +181,11 @@ JSLock::DropAllLocks::DropAllLocks(bool lockingForReal)
{
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.
@@ -146,6 +198,8 @@ JSLock::DropAllLocks::~DropAllLocks()
{
for (intptr_t i = 0; i < m_lockCount; i++)
JSLock::lock(m_lockingForReal);
+
+ --lockDropDepth;
}
#else
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.cpp
index d4310fc..937dc2b 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -37,13 +37,13 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
// JSValue methods
-JSValuePtr JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
+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&, JSValuePtr&)
+bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue&)
{
ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
@@ -69,8 +69,7 @@ UString JSNotAnObject::toString(ExecState* exec) const
JSObject* JSNotAnObject::toObject(ExecState* exec) const
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return m_exception;
}
@@ -95,12 +94,12 @@ bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&)
return false;
}
-void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValuePtr, PutPropertySlot&)
+void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue, PutPropertySlot&)
{
ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
}
-void JSNotAnObject::put(ExecState* exec, unsigned, JSValuePtr)
+void JSNotAnObject::put(ExecState* exec, unsigned, JSValue)
{
ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h
index c69593f..a8e36bd 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNotAnObject.h
@@ -60,15 +60,15 @@ namespace JSC {
{
}
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
private:
// JSValue methods
- virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&);
+ 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;
@@ -81,8 +81,8 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
+ 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);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.cpp
index efda0c6..669440b 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -28,12 +28,14 @@
namespace JSC {
-JSValuePtr JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
+#if !USE(ALTERNATE_JSIMMEDIATE)
+
+JSValue JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
return const_cast<JSNumberCell*>(this);
}
-bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
+bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
{
number = m_value;
value = this;
@@ -96,29 +98,40 @@ bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const
return true;
}
-JSValuePtr JSNumberCell::getJSNumber()
+JSValue JSNumberCell::getJSNumber()
{
return this;
}
-NEVER_INLINE JSValuePtr jsNumberCell(ExecState* exec, double d)
+JSValue jsNumberCell(ExecState* exec, double d)
{
return new (exec) JSNumberCell(exec, d);
}
-NEVER_INLINE JSValuePtr jsNaN(ExecState* exec)
+JSValue jsNumberCell(JSGlobalData* globalData, double d)
{
- return new (exec) JSNumberCell(exec, NaN);
+ return new (globalData) JSNumberCell(globalData, d);
}
-NEVER_INLINE JSValuePtr jsNumberCell(JSGlobalData* globalData, double d)
+JSValue jsAPIMangledNumber(ExecState* exec, double d)
{
- return new (globalData) JSNumberCell(globalData, d);
+ return new (exec) JSNumberCell(JSNumberCell::APIMangled, d);
+}
+
+#else
+
+JSValue jsNumberCell(ExecState*, double)
+{
+ ASSERT_NOT_REACHED();
+ return JSValue();
}
-NEVER_INLINE JSValuePtr jsNaN(JSGlobalData* globalData)
+JSValue jsAPIMangledNumber(ExecState*, double)
{
- return new (globalData) JSNumberCell(globalData, NaN);
+ ASSERT_NOT_REACHED();
+ return JSValue();
}
+#endif
+
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h
index 00d190d..a35e210 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSNumberCell.h
@@ -32,6 +32,14 @@
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;
@@ -43,15 +51,14 @@ namespace JSC {
class JSNumberCell : public JSCell {
friend class JIT;
- friend JSValuePtr jsNumberCell(JSGlobalData*, double);
- friend JSValuePtr jsNaN(JSGlobalData*);
- friend JSValuePtr jsNumberCell(ExecState*, double);
- friend JSValuePtr jsNaN(ExecState*);
+ friend JSValue jsNumberCell(JSGlobalData*, double);
+ friend JSValue jsNumberCell(ExecState*, double);
+ friend JSValue jsAPIMangledNumber(ExecState*, double);
public:
double value() const { return m_value; }
- virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& 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;
@@ -59,10 +66,10 @@ namespace JSC {
virtual UString toThisString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
- virtual JSValuePtr getJSNumber();
+ virtual JSValue getJSNumber();
- int32_t toInt32() const;
- uint32_t toUInt32() const;
+ static const uintptr_t JSAPIMangledMagicNumber = 0xbbadbeef;
+ bool isAPIMangledNumber() const { return m_structure == reinterpret_cast<Structure*>(JSAPIMangledMagicNumber); }
void* operator new(size_t size, ExecState* exec)
{
@@ -82,7 +89,7 @@ namespace JSC {
#endif
}
- static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
private:
JSNumberCell(JSGlobalData* globalData, double value)
@@ -97,6 +104,13 @@ namespace JSC {
{
}
+ 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;
@@ -104,157 +118,361 @@ namespace JSC {
double m_value;
};
- extern const double NaN;
- extern const double Inf;
+ JSValue jsNumberCell(JSGlobalData*, double);
- JSNumberCell* asNumberCell(JSValuePtr);
+ 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());
+ }
- JSValuePtr jsNumberCell(JSGlobalData*, double);
- JSValuePtr jsNaN(JSGlobalData*);
- JSValuePtr jsNumberCell(ExecState*, double);
- JSValuePtr jsNaN(ExecState*);
- inline JSNumberCell* asNumberCell(JSValuePtr value)
+ inline JSValue::JSValue(ExecState* exec, double d)
{
- ASSERT(asCell(value)->isNumber());
- return static_cast<JSNumberCell*>(asCell(value));
+ JSValue v = JSImmediate::from(d);
+ *this = v ? v : jsNumberCell(exec, d);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, double d)
+ inline JSValue::JSValue(ExecState* exec, int i)
{
- JSValuePtr v = JSImmediate::from(d);
- return v ? v : jsNumberCell(exec, d);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, short i)
+ inline JSValue::JSValue(ExecState* exec, unsigned i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned short i)
+ inline JSValue::JSValue(ExecState* exec, long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i)
+ inline JSValue::JSValue(ExecState* exec, unsigned long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned i)
+ inline JSValue::JSValue(ExecState* exec, long long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long i)
+ inline JSValue::JSValue(ExecState* exec, unsigned long long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long i)
+ inline JSValue::JSValue(JSGlobalData* globalData, double d)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValue v = JSImmediate::from(d);
+ *this = v ? v : jsNumberCell(globalData, d);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long long i)
+ inline JSValue::JSValue(JSGlobalData* globalData, int i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, static_cast<double>(i));
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long long i)
+ inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, static_cast<double>(i));
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, double d)
+ inline JSValue::JSValue(JSGlobalData* globalData, long i)
{
- JSValuePtr v = JSImmediate::from(d);
- return v ? v : jsNumberCell(globalData, d);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, short i)
+ inline JSValue::JSValue(JSGlobalData* globalData, unsigned long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i)
+ inline JSValue::JSValue(JSGlobalData* globalData, long long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
+ inline JSValue::JSValue(JSGlobalData* globalData, unsigned long long i)
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValue v = JSImmediate::from(i);
+ *this = v ? v : jsNumberCell(globalData, static_cast<double>(i));
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
+ inline bool JSValue::isDoubleNumber() const
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ return isNumberCell(asValue());
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
+ inline double JSValue::getDoubleNumber() const
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ return asNumberCell(asValue())->value();
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
+ inline bool JSValue::isNumber() const
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ return JSImmediate::isNumber(asValue()) || isDoubleNumber();
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i)
+ inline double JSValue::uncheckedGetNumber() const
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ ASSERT(isNumber());
+ return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
}
- ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i)
+ inline bool JSValue::isAPIMangledNumber()
{
- JSValuePtr v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ ASSERT(isNumber());
+ return JSImmediate::isImmediate(asValue()) ? false : asNumberCell(asValue())->isAPIMangledNumber();
}
- // --- JSValue inlines ----------------------------
+#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(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
+ 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 int32_t JSNumberCell::toInt32() const
+ inline JSValue::JSValue(JSGlobalData*, short i)
{
- if (m_value >= -2147483648.0 && m_value < 2147483648.0)
- return static_cast<int32_t>(m_value);
- bool scratch;
- return JSC::toInt32SlowCase(m_value, scratch);
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
}
- inline uint32_t JSNumberCell::toUInt32() const
+ inline JSValue::JSValue(JSGlobalData*, unsigned short i)
{
- if (m_value >= 0.0 && m_value < 4294967296.0)
- return static_cast<uint32_t>(m_value);
- bool scratch;
- return JSC::toUInt32SlowCase(m_value, scratch);
+ ASSERT(JSImmediate::from(i));
+ *this = JSImmediate::from(i);
}
- ALWAYS_INLINE JSValuePtr JSValue::toJSNumber(ExecState* exec) const
+ inline JSValue jsNaN(ExecState* exec)
{
- return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp
index d38c325..415c25d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.cpp
@@ -69,11 +69,13 @@ void JSObject::mark()
JSCell::mark();
m_structure->mark();
+ PropertyStorage storage = propertyStorage();
+
size_t storageSize = m_structure->propertyStorageSize();
for (size_t i = 0; i < storageSize; ++i) {
- JSValuePtr v = m_propertyStorage[i];
- if (!v->marked())
- v->mark();
+ JSValue v = JSValue::decode(storage[i]);
+ if (!v.marked())
+ v.mark();
}
JSOBJECT_MARK_END();
@@ -98,18 +100,18 @@ static void throwSetterError(ExecState* exec)
}
// ECMA 8.6.2.2
-void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+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())
+ if (!value.isObject() && !value.isNull())
return;
- JSValuePtr nextPrototypeValue = value;
- while (nextPrototypeValue && nextPrototypeValue->isObject()) {
+ JSValue nextPrototypeValue = value;
+ while (nextPrototypeValue && nextPrototypeValue.isObject()) {
JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject();
if (nextPrototype == this) {
throwError(exec, GeneralError, "cyclic __proto__ value");
@@ -123,22 +125,23 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
}
// Check if there are any setters or getters in the prototype chain
- JSValuePtr prototype;
+ JSValue prototype;
for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
prototype = obj->prototype();
- if (prototype->isNull()) {
- putDirect(propertyName, value, 0, true, slot);
+ if (prototype.isNull()) {
+ putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
return;
}
}
unsigned attributes;
- if ((m_structure->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
+ JSCell* specificValue;
+ if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly)
return;
for (JSObject* obj = this; ; obj = asObject(prototype)) {
- if (JSValuePtr gs = obj->getDirect(propertyName)) {
- if (gs->isGetterSetter()) {
+ if (JSValue gs = obj->getDirect(propertyName)) {
+ if (gs.isGetterSetter()) {
JSObject* setterFunc = asGetterSetter(gs)->setter();
if (!setterFunc) {
throwSetterError(exec);
@@ -147,7 +150,7 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
CallData callData;
CallType callType = setterFunc->getCallData(callData);
- ArgList args;
+ MarkedArgumentBuffer args;
args.append(value);
call(exec, setterFunc, callType, callData, this, args);
return;
@@ -159,26 +162,31 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
}
prototype = obj->prototype();
- if (prototype->isNull())
+ if (prototype.isNull())
break;
}
- putDirect(propertyName, value, 0, true, slot);
+ putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
return;
}
-void JSObject::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
+void JSObject::put(ExecState* exec, unsigned propertyName, JSValue value)
{
PutPropertySlot slot;
put(exec, Identifier::from(exec, propertyName), value, slot);
}
-void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
- putDirect(propertyName, value, attributes);
+ putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot);
}
-void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValuePtr value, unsigned attributes)
+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);
}
@@ -199,7 +207,8 @@ bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const
bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
unsigned attributes;
- if (m_structure->get(propertyName, attributes) != WTF::notFound) {
+ JSCell* specificValue;
+ if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) {
if ((attributes & DontDelete))
return false;
removeDirect(propertyName);
@@ -226,11 +235,11 @@ bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName)
return deleteProperty(exec, Identifier::from(exec, propertyName));
}
-static ALWAYS_INLINE JSValuePtr callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
+static ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
{
- JSValuePtr function = object->get(exec, propertyName);
+ JSValue function = object->get(exec, propertyName);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return exec->exception();
@@ -239,35 +248,35 @@ static ALWAYS_INLINE JSValuePtr callDefaultValueFunction(ExecState* exec, const
if (exec->hadException())
return exec->exception();
- JSValuePtr result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
- ASSERT(!result->isGetterSetter());
+ JSValue result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
+ ASSERT(!result.isGetterSetter());
if (exec->hadException())
return exec->exception();
- if (result->isObject())
- return noValue();
+ if (result.isObject())
+ return JSValue();
return result;
}
-bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& result)
+bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
{
result = defaultValue(exec, PreferNumber);
- number = result->toNumber(exec);
- return !result->isString();
+ number = result.toNumber(exec);
+ return !result.isString();
}
// ECMA 8.6.2.6
-JSValuePtr JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
+JSValue JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
{
// Must call toString first for Date objects.
if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) {
- JSValuePtr value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
+ JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
if (value)
return value;
value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
if (value)
return value;
} else {
- JSValuePtr value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
+ JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
if (value)
return value;
value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
@@ -293,8 +302,8 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi
void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
{
- JSValuePtr object = getDirect(propertyName);
- if (object && object->isGetterSetter()) {
+ JSValue object = getDirect(propertyName);
+ if (object && object.isGetterSetter()) {
ASSERT(m_structure->hasGetterSetterProperties());
asGetterSetter(object)->setGetter(getterFunction);
return;
@@ -302,7 +311,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
PutPropertySlot slot;
GetterSetter* getterSetter = new (exec) GetterSetter;
- putDirect(propertyName, getterSetter, None, true, slot);
+ 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
@@ -320,8 +329,8 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
{
- JSValuePtr object = getDirect(propertyName);
- if (object && object->isGetterSetter()) {
+ JSValue object = getDirect(propertyName);
+ if (object && object.isGetterSetter()) {
ASSERT(m_structure->hasGetterSetterProperties());
asGetterSetter(object)->setSetter(setterFunction);
return;
@@ -329,7 +338,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
PutPropertySlot slot;
GetterSetter* getterSetter = new (exec) GetterSetter;
- putDirect(propertyName, getterSetter, None, true, slot);
+ 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
@@ -345,12 +354,12 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
getterSetter->setSetter(setterFunction);
}
-JSValuePtr JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
+JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
{
JSObject* object = this;
while (true) {
- if (JSValuePtr value = object->getDirect(propertyName)) {
- if (!value->isGetterSetter())
+ if (JSValue value = object->getDirect(propertyName)) {
+ if (!value.isGetterSetter())
return jsUndefined();
JSObject* functionObject = asGetterSetter(value)->getter();
if (!functionObject)
@@ -358,18 +367,18 @@ JSValuePtr JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
return functionObject;
}
- if (!object->prototype() || !object->prototype()->isObject())
+ if (!object->prototype() || !object->prototype().isObject())
return jsUndefined();
object = asObject(object->prototype());
}
}
-JSValuePtr JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
+JSValue JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
{
JSObject* object = this;
while (true) {
- if (JSValuePtr value = object->getDirect(propertyName)) {
- if (!value->isGetterSetter())
+ if (JSValue value = object->getDirect(propertyName)) {
+ if (!value.isGetterSetter())
return jsUndefined();
JSObject* functionObject = asGetterSetter(value)->setter();
if (!functionObject)
@@ -377,24 +386,24 @@ JSValuePtr JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
return functionObject;
}
- if (!object->prototype() || !object->prototype()->isObject())
+ if (!object->prototype() || !object->prototype().isObject())
return jsUndefined();
object = asObject(object->prototype());
}
}
-bool JSObject::hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr proto)
+bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto)
{
- if (!proto->isObject()) {
- throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
+ if (!value.isObject())
return false;
- }
- if (!value->isObject())
+ 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())) {
+ while ((object = object->prototype().getObject())) {
if (proto == object)
return true;
}
@@ -411,7 +420,8 @@ bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyN
bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
{
- if (m_structure->get(propertyName, attributes) != WTF::notFound)
+ JSCell* specificValue;
+ if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
return true;
// Look in the static hashtable of properties
@@ -424,6 +434,19 @@ bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& property
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)
{
m_structure->getEnumerablePropertyNames(exec, propertyNames, this);
@@ -436,18 +459,18 @@ bool JSObject::toBoolean(ExecState*) const
double JSObject::toNumber(ExecState* exec) const
{
- JSValuePtr primitive = toPrimitive(exec, PreferNumber);
+ JSValue primitive = toPrimitive(exec, PreferNumber);
if (exec->hadException()) // should be picked up soon in Nodes.cpp
return 0.0;
- return primitive->toNumber(exec);
+ return primitive.toNumber(exec);
}
UString JSObject::toString(ExecState* exec) const
{
- JSValuePtr primitive = toPrimitive(exec, PreferString);
+ JSValue primitive = toPrimitive(exec, PreferString);
if (exec->hadException())
return "";
- return primitive->toString(exec);
+ return primitive.toString(exec);
}
JSObject* JSObject::toObject(ExecState*) const
@@ -471,27 +494,27 @@ void JSObject::removeDirect(const Identifier& propertyName)
if (m_structure->isDictionary()) {
offset = m_structure->removePropertyWithoutTransition(propertyName);
if (offset != WTF::notFound)
- m_propertyStorage[offset] = jsUndefined();
+ putDirectOffset(offset, jsUndefined());
return;
}
RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
- if (offset != WTF::notFound)
- m_propertyStorage[offset] = jsUndefined();
setStructure(structure.release());
+ if (offset != WTF::notFound)
+ putDirectOffset(offset, jsUndefined());
}
void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
{
- putDirect(Identifier(exec, function->name(&exec->globalData())), function, attr);
+ putDirectFunction(Identifier(exec, function->name(&exec->globalData())), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
{
- putDirectWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
+ putDirectFunctionWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
}
-NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValuePtr* location)
+NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
{
if (JSObject* getterFunction = asGetterSetter(*location)->getter())
slot.setGetterSlot(getterFunction);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h
index 5918b9d..54805f2 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSObject.h
@@ -32,9 +32,17 @@
#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;
@@ -49,9 +57,12 @@ namespace JSC {
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 JSValuePtr* PropertyStorage;
+ typedef EncodedJSValue* PropertyStorage;
+ typedef const EncodedJSValue* ConstPropertyStorage;
class JSObject : public JSCell {
friend class BatchedTransitionOptimizer;
@@ -69,18 +80,16 @@ namespace JSC {
bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
- JSValuePtr prototype() const;
- void setPrototype(JSValuePtr prototype);
+ JSValue prototype() const;
+ void setPrototype(JSValue prototype);
void setStructure(PassRefPtr<Structure>);
Structure* inheritorID();
- PropertyStorage& propertyStorage() { return m_propertyStorage; }
-
virtual UString className() const;
- JSValuePtr get(ExecState*, const Identifier& propertyName) const;
- JSValuePtr get(ExecState*, unsigned propertyName) 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&);
@@ -88,11 +97,12 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValuePtr value);
+ 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, JSValuePtr value, unsigned attributes);
- virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValuePtr value, unsigned attributes);
+ 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;
@@ -103,14 +113,14 @@ namespace JSC {
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
- virtual JSValuePtr defaultValue(ExecState*, PreferredPrimitiveType) const;
+ virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
- virtual bool hasInstance(ExecState*, JSValuePtr, JSValuePtr prototypeProperty);
+ virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
- virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
+ 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;
@@ -120,34 +130,31 @@ namespace JSC {
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.
- JSValuePtr getDirect(const Identifier& propertyName) const
+ JSValue getDirect(const Identifier& propertyName) const
{
size_t offset = m_structure->get(propertyName);
- return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
+ return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
}
- JSValuePtr* getDirectLocation(const Identifier& propertyName)
+ JSValue* getDirectLocation(const Identifier& propertyName)
{
size_t offset = m_structure->get(propertyName);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- JSValuePtr* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+ JSValue* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
{
- size_t offset = m_structure->get(propertyName, attributes);
+ JSCell* specificFunction;
+ size_t offset = m_structure->get(propertyName, attributes, specificFunction);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- size_t offsetForLocation(JSValuePtr* location)
- {
- return location - m_propertyStorage;
- }
-
- JSValuePtr* locationForOffset(size_t offset)
+ size_t offsetForLocation(JSValue* location) const
{
- return &m_propertyStorage[offset];
+ return location - reinterpret_cast<const JSValue*>(propertyStorage());
}
void transitionTo(Structure*);
@@ -156,36 +163,42 @@ namespace JSC {
bool hasCustomProperties() { return !m_structure->isEmpty(); }
bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
- void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
- void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ 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, JSValuePtr value, 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.
- JSValuePtr getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
- void putDirectOffset(size_t offset, JSValuePtr value) { m_propertyStorage[offset] = value; }
+ 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&, JSValuePtr* location);
+ void fillGetterPropertySlot(PropertySlot&, JSValue* location);
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
- virtual JSValuePtr lookupGetter(ExecState*, const Identifier& propertyName);
- virtual JSValuePtr lookupSetter(ExecState*, const Identifier& propertyName);
+ 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 usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
+ bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
- static const size_t inlineStorageCapacity = 2;
+ static const size_t inlineStorageCapacity = 3;
static const size_t nonInlineBaseStorageCapacity = 16;
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
}
@@ -194,6 +207,23 @@ namespace JSC {
bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
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;
@@ -201,15 +231,17 @@ namespace JSC {
RefPtr<Structure> m_inheritorID;
- PropertyStorage m_propertyStorage;
- JSValuePtr m_inlineStorage[inlineStorageCapacity];
+ union {
+ PropertyStorage m_externalStorage;
+ EncodedJSValue m_inlineStorage[inlineStorageCapacity];
+ };
};
- JSObject* asObject(JSValuePtr);
+ JSObject* asObject(JSValue);
JSObject* constructEmptyObject(ExecState*);
-inline JSObject* asObject(JSValuePtr value)
+inline JSObject* asObject(JSValue value)
{
ASSERT(asCell(value)->isObject());
return static_cast<JSObject*>(asCell(value));
@@ -217,28 +249,27 @@ inline JSObject* asObject(JSValuePtr value)
inline JSObject::JSObject(PassRefPtr<Structure> structure)
: JSCell(structure.releaseRef()) // ~JSObject balances this ref()
- , m_propertyStorage(m_inlineStorage)
{
ASSERT(m_structure);
ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
ASSERT(m_structure->isEmpty());
- ASSERT(prototype()->isNull() || Heap::heap(this) == Heap::heap(prototype()));
+ ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
}
inline JSObject::~JSObject()
{
ASSERT(m_structure);
- if (m_propertyStorage != m_inlineStorage)
- delete [] m_propertyStorage;
+ if (!isUsingInlineStorage())
+ delete [] m_externalStorage;
m_structure->deref();
}
-inline JSValuePtr JSObject::prototype() const
+inline JSValue JSObject::prototype() const
{
return m_structure->storedPrototype();
}
-inline void JSObject::setPrototype(JSValuePtr prototype)
+inline void JSObject::setPrototype(JSValue prototype)
{
ASSERT(prototype);
RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
@@ -258,6 +289,11 @@ inline Structure* JSObject::inheritorID()
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) {
@@ -270,13 +306,13 @@ inline bool JSCell::isObject(const ClassInfo* info) const
// this method is here to be after the inline declaration of JSCell::isObject
inline bool JSValue::isObject(const ClassInfo* classInfo) const
{
- return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);
+ return isCell() && asCell()->isObject(classInfo);
}
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (JSValuePtr* location = getDirectLocation(propertyName)) {
- if (m_structure->hasGetterSetterProperties() && location[0]->isGetterSetter())
+ if (JSValue* location = getDirectLocation(propertyName)) {
+ if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter())
fillGetterPropertySlot(slot, location);
else
slot.setValueSlot(this, location, offsetForLocation(location));
@@ -295,8 +331,8 @@ ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Ide
ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
{
unsigned attributes;
- if (JSValuePtr* location = getDirectLocation(propertyName, attributes)) {
- if (m_structure->hasGetterSetterProperties() && location[0]->isGetterSetter()) {
+ if (JSValue* location = getDirectLocation(propertyName, attributes)) {
+ if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter()) {
slotIsWriteable = false;
fillGetterPropertySlot(slot, location);
} else {
@@ -339,8 +375,8 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert
while (true) {
if (object->fastGetOwnPropertySlot(exec, propertyName, slot))
return true;
- JSValuePtr prototype = object->prototype();
- if (!prototype->isObject())
+ JSValue prototype = object->prototype();
+ if (!prototype.isObject())
return false;
object = asObject(prototype);
}
@@ -352,14 +388,14 @@ inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, Pr
while (true) {
if (object->getOwnPropertySlot(exec, propertyName, slot))
return true;
- JSValuePtr prototype = object->prototype();
- if (!prototype->isObject())
+ JSValue prototype = object->prototype();
+ if (!prototype.isObject())
return false;
object = asObject(prototype);
}
}
-inline JSValuePtr JSObject::get(ExecState* exec, const Identifier& propertyName) const
+inline JSValue JSObject::get(ExecState* exec, const Identifier& propertyName) const
{
PropertySlot slot(this);
if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
@@ -368,7 +404,7 @@ inline JSValuePtr JSObject::get(ExecState* exec, const Identifier& propertyName)
return jsUndefined();
}
-inline JSValuePtr JSObject::get(ExecState* exec, unsigned propertyName) const
+inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
{
PropertySlot slot(this);
if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
@@ -377,80 +413,139 @@ inline JSValuePtr JSObject::get(ExecState* exec, unsigned propertyName) const
return jsUndefined();
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr)
-{
- PutPropertySlot slot;
- putDirect(propertyName, value, attr, false, slot);
-}
-
-inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+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;
- size_t offset = m_structure->get(propertyName, 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;
- m_propertyStorage[offset] = value;
- slot.setExistingProperty(this, offset);
+ putDirectOffset(offset, value);
+ if (!specificFunction && !currentSpecificFunction)
+ slot.setExistingProperty(this, offset);
return;
}
size_t currentCapacity = m_structure->propertyStorageCapacity();
- offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
+ offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
ASSERT(offset < m_structure->propertyStorageCapacity());
- m_propertyStorage[offset] = value;
- slot.setNewProperty(this, offset);
+ 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, offset)) {
+ if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) {
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
- m_propertyStorage[offset] = value;
- slot.setNewProperty(this, offset);
- slot.setWasTransition(true);
setStructure(structure.release());
+ putDirectOffset(offset, value);
+ // See comment on setNewProperty call below.
+ if (!specificFunction)
+ slot.setNewProperty(this, offset);
return;
}
unsigned currentAttributes;
- offset = m_structure->get(propertyName, currentAttributes);
+ JSCell* currentSpecificFunction;
+ offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
return;
- m_propertyStorage[offset] = value;
+
+ 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, offset);
+ RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset);
if (currentCapacity != structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
ASSERT(offset < structure->propertyStorageCapacity());
- m_propertyStorage[offset] = value;
- slot.setNewProperty(this, offset);
- slot.setWasTransition(true);
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::putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+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);
+ size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value);
if (currentCapacity != m_structure->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
- m_propertyStorage[offset] = value;
+ putDirectOffset(offset, value);
}
inline void JSObject::transitionTo(Structure* newStructure)
@@ -460,21 +555,23 @@ inline void JSObject::transitionTo(Structure* newStructure)
setStructure(newStructure);
}
-inline JSValuePtr JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
{
return defaultValue(exec, preferredType);
}
-inline JSValuePtr JSValue::get(ExecState* exec, const Identifier& propertyName) const
+inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName) const
{
- PropertySlot slot(this);
+ PropertySlot slot(asValue());
return get(exec, propertyName, slot);
}
-inline JSValuePtr JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
+inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ 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);
@@ -484,22 +581,22 @@ inline JSValuePtr JSValue::get(ExecState* exec, const Identifier& propertyName,
if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
ASSERT(cell->isObject());
- JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
- if (!prototype->isObject())
+ JSValue prototype = static_cast<JSObject*>(cell)->prototype();
+ if (!prototype.isObject())
return jsUndefined();
cell = asObject(prototype);
}
}
-inline JSValuePtr JSValue::get(ExecState* exec, unsigned propertyName) const
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
{
- PropertySlot slot(this);
+ PropertySlot slot(asValue());
return get(exec, propertyName, slot);
}
-inline JSValuePtr JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ if (UNLIKELY(!isCell())) {
JSObject* prototype = JSImmediate::prototype(asValue(), exec);
if (!prototype->getPropertySlot(exec, propertyName, slot))
return jsUndefined();
@@ -510,25 +607,25 @@ inline JSValuePtr JSValue::get(ExecState* exec, unsigned propertyName, PropertyS
if (cell->getOwnPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
ASSERT(cell->isObject());
- JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
- if (!prototype->isObject())
+ JSValue prototype = static_cast<JSObject*>(cell)->prototype();
+ if (!prototype.isObject())
return jsUndefined();
- cell = prototype->asCell();
+ cell = prototype.asCell();
}
}
-inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ 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, JSValuePtr value)
+inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ if (UNLIKELY(!isCell())) {
JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
return;
}
@@ -539,14 +636,20 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_
{
ASSERT(newSize > oldSize);
- JSValuePtr* oldPropertyStorage = m_propertyStorage;
- m_propertyStorage = new JSValuePtr[newSize];
+ // 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)
- m_propertyStorage[i] = oldPropertyStorage[i];
+ newPropertyStorage[i] = oldPropertyStorage[i];
- if (oldPropertyStorage != m_inlineStorage)
+ if (!wasInline)
delete [] oldPropertyStorage;
+
+ m_externalStorage = newPropertyStorage;
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index ec8efea..8c7b53d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -37,13 +37,13 @@ JSPropertyNameIterator::~JSPropertyNameIterator()
{
}
-JSValuePtr JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
ASSERT_NOT_REACHED();
- return noValue();
+ return JSValue();
}
-bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValuePtr&)
+bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue&)
{
ASSERT_NOT_REACHED();
return false;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h
index fddb4f6..9817c07 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -40,12 +40,12 @@ namespace JSC {
class JSPropertyNameIterator : public JSCell {
public:
- static JSPropertyNameIterator* create(ExecState*, JSValuePtr);
+ static JSPropertyNameIterator* create(ExecState*, JSValue);
virtual ~JSPropertyNameIterator();
- virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double&, JSValuePtr&);
+ 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;
@@ -53,7 +53,7 @@ namespace JSC {
virtual void mark();
- JSValuePtr next(ExecState*);
+ JSValue next(ExecState*);
void invalidate();
private:
@@ -83,23 +83,23 @@ inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, PassRefP
{
}
-inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValuePtr v)
+inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v)
{
- if (v->isUndefinedOrNull())
+ if (v.isUndefinedOrNull())
return new (exec) JSPropertyNameIterator;
- JSObject* o = v->toObject(exec);
+ JSObject* o = v.toObject(exec);
PropertyNameArray propertyNames(exec);
o->getPropertyNames(exec, propertyNames);
return new (exec) JSPropertyNameIterator(o, propertyNames.releaseData());
}
-inline JSValuePtr JSPropertyNameIterator::next(ExecState* exec)
+inline JSValue JSPropertyNameIterator::next(ExecState* exec)
{
if (m_position == m_end)
- return noValue();
+ return JSValue();
- if (m_data->cachedStructure() == m_object->structure() && structureChainsAreEqual(m_data->cachedPrototypeChain(), m_object->structure()->cachedPrototypeChain()))
+ if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec))
return jsOwnedString(exec, (*m_position++).ustring());
do {
@@ -108,7 +108,7 @@ inline JSValuePtr JSPropertyNameIterator::next(ExecState* exec)
m_position++;
} while (m_position != m_end);
- return noValue();
+ return JSValue();
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index 4196822..0253fdd 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -44,7 +44,7 @@ JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
return exec->globalThisValue();
}
-void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&)
+void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&)
{
if (symbolTablePut(propertyName, value))
return;
@@ -52,7 +52,7 @@ void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValu
ASSERT_NOT_REACHED();
}
-void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes)
{
if (symbolTablePutWithAttributes(propertyName, value, attributes))
return;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h
index e1400b7..7e7ce65 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -43,7 +43,7 @@ namespace JSC{
};
public:
- JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValuePtr value, unsigned attributes)
+ JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue value, unsigned attributes)
: JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData())
{
d()->registerStore = value;
@@ -55,10 +55,10 @@ namespace JSC{
virtual JSObject* toThisObject(ExecState*) const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
- virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
- void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes);
+ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+ void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
- static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
private:
JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp
index e644bf6..86f95e0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.cpp
@@ -30,12 +30,12 @@
namespace JSC {
-JSValuePtr JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
return const_cast<JSString*>(this);
}
-bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
+bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
{
value = this;
number = m_value.toDouble();
@@ -88,9 +88,13 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam
// 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 (JSValuePtr prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype->isNull(); prototype = object->prototype()) {
+ for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
object = asObject(prototype);
if (object->getOwnPropertySlot(exec, propertyName, slot))
return true;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h
index a584a3c..900c565 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSString.h
@@ -60,7 +60,7 @@ namespace JSC {
class JSString : public JSCell {
friend class JIT;
- friend class Interpreter;
+ friend class VPtrSet;
public:
JSString(JSGlobalData* globalData, const UString& value)
@@ -90,7 +90,7 @@ namespace JSC {
bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
JSString* getIndex(JSGlobalData*, unsigned);
- static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
@@ -99,8 +99,8 @@ namespace JSC {
{
}
- virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& 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 JSObject* toObject(ExecState*) const;
@@ -117,9 +117,9 @@ namespace JSC {
UString m_value;
};
- JSString* asString(JSValuePtr);
+ JSString* asString(JSValue);
- inline JSString* asString(JSValuePtr value)
+ inline JSString* asString(JSValue value)
{
ASSERT(asCell(value)->isString());
return static_cast<JSString*>(asCell(value));
@@ -202,6 +202,8 @@ namespace JSC {
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)
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp
index 73580b0..885914d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp
@@ -33,18 +33,16 @@ static const double D32 = 4294967296.0;
// ECMA 9.4
double JSValue::toInteger(ExecState* exec) const
{
- int32_t i;
- if (getTruncatedInt32(i))
- return i;
+ if (isInt32Fast())
+ return getInt32Fast();
double d = toNumber(exec);
return isnan(d) ? 0.0 : trunc(d);
}
double JSValue::toIntegerPreserveNaN(ExecState* exec) const
{
- int32_t i;
- if (getTruncatedInt32(i))
- return i;
+ if (isInt32Fast())
+ return getInt32Fast();
return trunc(toNumber(exec));
}
@@ -68,11 +66,6 @@ int32_t toInt32SlowCase(double d, bool& ok)
return static_cast<int32_t>(d32);
}
-int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
-{
- return JSC::toInt32SlowCase(toNumber(exec), ok);
-}
-
uint32_t toUInt32SlowCase(double d, bool& ok)
{
ok = true;
@@ -91,14 +84,4 @@ uint32_t toUInt32SlowCase(double d, bool& ok)
return static_cast<uint32_t>(d32);
}
-uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
-{
- return JSC::toUInt32SlowCase(toNumber(exec), ok);
-}
-
-float JSValue::toFloat(ExecState* exec) const
-{
- return static_cast<float>(toNumber(exec));
-}
-
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h
index f04b67f..391425c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.h
@@ -28,12 +28,15 @@
#include "CallData.h"
#include "ConstructData.h"
-#include <wtf/Noncopyable.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;
@@ -45,12 +48,67 @@ namespace JSC {
enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
- class JSValue : Noncopyable {
- protected:
- JSValue() { }
- virtual ~JSValue() { }
+ 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;
@@ -65,7 +123,7 @@ namespace JSC {
// Extracting the value.
bool getBoolean(bool&) const;
bool getBoolean() const; // false if not a boolean
- double getNumber() const; // NaN if not a number
+ bool getNumber(double&) const;
double uncheckedGetNumber() const;
bool getString(UString&) const;
UString getString() const; // null string if not a string
@@ -80,143 +138,282 @@ namespace JSC {
bool getTruncatedUInt32(uint32_t&) const;
// Basic conversions.
- JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
- bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&);
+ 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;
- JSValuePtr toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
-
+ 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;
-
- // Floating point conversions.
- float toFloat(ExecState*) 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.
- JSValuePtr get(ExecState*, const Identifier& propertyName) const;
- JSValuePtr get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
- JSValuePtr get(ExecState*, unsigned propertyName) const;
- JSValuePtr get(ExecState*, unsigned propertyName, PropertySlot&) const;
- void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
- void put(ExecState*, unsigned propertyName, JSValuePtr);
- bool deleteProperty(ExecState*, const Identifier& propertyName);
- bool deleteProperty(ExecState*, unsigned propertyName);
+ 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*);
- JSValuePtr getJSNumber(); // 0 if this is not a JSNumber or number object
+ 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);
- JSValuePtr asValue() const;
+ JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
+ bool isCell() const;
JSCell* asCell() const;
private:
- bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
- bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- int32_t toInt32SlowCase(ExecState*, bool& ok) const;
- uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
+ enum HashTableDeletedValueTag { HashTableDeletedValue };
+ JSValue(HashTableDeletedValueTag);
+
+ inline const JSValue asValue() const { return *this; }
+
+ bool isDoubleNumber() const;
+ double getDoubleNumber() const;
+
+ JSCell* m_ptr;
};
- class JSImmediate;
- class JSValueEncodedAsPointer;
+ 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)); }
+ };
- class JSValuePtr {
- friend class JSImmediate;
+ // Stand-alone helper functions.
+ inline JSValue jsNull()
+ {
+ return JSValue(JSValue::JSNull);
+ }
- static JSValuePtr makeImmediate(intptr_t value)
- {
- return JSValuePtr(reinterpret_cast<JSValue*>(value));
- }
+ inline JSValue jsUndefined()
+ {
+ return JSValue(JSValue::JSUndefined);
+ }
- intptr_t immediateValue()
- {
- return reinterpret_cast<intptr_t>(m_ptr);
- }
-
- public:
- JSValuePtr()
- : m_ptr(0)
- {
- }
+ inline JSValue jsBoolean(bool b)
+ {
+ return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
+ }
- JSValuePtr(JSValue* ptr)
- : m_ptr(ptr)
- {
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
+ {
+ return JSValue(exec, d);
+ }
- JSValuePtr(const JSValue* ptr)
- : m_ptr(const_cast<JSValue*>(ptr))
- {
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
+ {
+ return JSValue(exec, i);
+ }
- JSValue* operator->() const
- {
- return m_ptr;
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
+ {
+ return JSValue(exec, i);
+ }
- operator bool() const
- {
- return m_ptr;
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
+ {
+ return JSValue(exec, i);
+ }
- bool operator==(const JSValuePtr other) const
- {
- return m_ptr == other.m_ptr;
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
+ {
+ return JSValue(exec, i);
+ }
- bool operator!=(const JSValuePtr other) const
- {
- return m_ptr != other.m_ptr;
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
+ {
+ return JSValue(exec, i);
+ }
- static JSValueEncodedAsPointer* encode(JSValuePtr value)
- {
- return reinterpret_cast<JSValueEncodedAsPointer*>(value.m_ptr);
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
+ {
+ return JSValue(exec, i);
+ }
- static JSValuePtr decode(JSValueEncodedAsPointer* ptr)
- {
- return JSValuePtr(reinterpret_cast<JSValue*>(ptr));
- }
+ ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
+ {
+ return JSValue(exec, i);
+ }
- private:
- JSValue* m_ptr;
- };
+ 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);
+ }
- inline JSValuePtr JSValue::asValue() const
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, short i)
{
- return JSValuePtr(this);
+ return JSValue(globalData, i);
}
- inline JSValuePtr noValue()
+ ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned short i)
{
- return JSValuePtr();
+ return JSValue(globalData, i);
}
- inline bool operator==(const JSValuePtr a, const JSValue* b) { return a == JSValuePtr(b); }
- inline bool operator==(const JSValue* a, const JSValuePtr b) { return JSValuePtr(a) == b; }
+ 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 JSValuePtr a, const JSValue* b) { return a != JSValuePtr(b); }
- inline bool operator!=(const JSValue* a, const JSValuePtr b) { return JSValuePtr(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; }
+
+ 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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h
index 9bf5c4f..b969da5 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSVariableObject.h
@@ -46,7 +46,7 @@ namespace JSC {
public:
SymbolTable& symbolTable() const { return *d->symbolTable; }
- virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes) = 0;
+ virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
virtual bool deleteProperty(ExecState*, const Identifier&);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -90,8 +90,8 @@ namespace JSC {
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
- bool symbolTablePut(const Identifier&, JSValuePtr);
- bool symbolTablePutWithAttributes(const Identifier&, JSValuePtr, unsigned attributes);
+ bool symbolTablePut(const Identifier&, JSValue);
+ bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes);
JSVariableObjectData* d;
};
@@ -117,7 +117,7 @@ namespace JSC {
return false;
}
- inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValuePtr value)
+ inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue value)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -130,7 +130,7 @@ namespace JSC {
return true;
}
- inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+ inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.cpp
index c791d93..fb57018 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.cpp
@@ -29,8 +29,8 @@ ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject);
void JSWrapperObject::mark()
{
JSObject::mark();
- if (m_internalValue && !m_internalValue->marked())
- m_internalValue->mark();
+ if (m_internalValue && !m_internalValue.marked())
+ m_internalValue.mark();
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h
index 4ca96f4..2a2e3c6 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSWrapperObject.h
@@ -33,25 +33,24 @@ namespace JSC {
explicit JSWrapperObject(PassRefPtr<Structure>);
public:
- JSValuePtr internalValue() const { return m_internalValue; }
- void setInternalValue(JSValuePtr);
+ JSValue internalValue() const { return m_internalValue; }
+ void setInternalValue(JSValue);
virtual void mark();
private:
- JSValuePtr m_internalValue;
+ JSValue m_internalValue;
};
inline JSWrapperObject::JSWrapperObject(PassRefPtr<Structure> structure)
: JSObject(structure)
- , m_internalValue(noValue())
{
}
- inline void JSWrapperObject::setInternalValue(JSValuePtr value)
+ inline void JSWrapperObject::setInternalValue(JSValue value)
{
ASSERT(value);
- ASSERT(!value->isObject());
+ ASSERT(!value.isObject());
m_internalValue = value;
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.cpp
new file mode 100644
index 0000000..10f9a13
--- /dev/null
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.cpp
@@ -0,0 +1,306 @@
+/*
+ * 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 <wtf/ASCIICType.h>
+
+namespace JSC {
+
+class LiteralParser::StackGuard {
+public:
+ StackGuard(LiteralParser* parser)
+ : m_parser(parser)
+ {
+ m_parser->m_depth++;
+ }
+ ~StackGuard()
+ {
+ m_parser->m_depth--;
+ }
+ bool isSafe() { return m_parser->m_depth < 10; }
+private:
+ LiteralParser* m_parser;
+};
+
+static bool isSafeStringCharacter(UChar c)
+{
+ return (c >= ' ' && c <= 0xff && c != '\\') || c == '\t';
+}
+
+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 '"':
+ return lexString(token);
+
+ 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;
+}
+
+LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token)
+{
+ ++m_ptr;
+ while (m_ptr < m_end && isSafeStringCharacter(*m_ptr) && *m_ptr != '"')
+ ++m_ptr;
+ if (m_ptr >= m_end || *m_ptr != '"') {
+ token.type = TokError;
+ token.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;
+ return TokNumber;
+}
+
+JSValue LiteralParser::parseStatement()
+{
+ StackGuard guard(this);
+ if (!guard.isSafe())
+ return abortParse();
+
+ switch (m_lexer.currentToken().type) {
+ case TokLBracket:
+ case TokNumber:
+ case TokString:
+ return parseExpression();
+ case TokLParen: {
+ m_lexer.next();
+ JSValue result = parseExpression();
+ if (m_aborted || m_lexer.currentToken().type != TokRParen)
+ return abortParse();
+ m_lexer.next();
+ return result;
+ }
+ default:
+ return abortParse();
+ }
+}
+
+JSValue LiteralParser::parseExpression()
+{
+ StackGuard guard(this);
+ if (!guard.isSafe())
+ return abortParse();
+ switch (m_lexer.currentToken().type) {
+ case TokLBracket:
+ return parseArray();
+ case TokLBrace:
+ return parseObject();
+ case TokString: {
+ Lexer::LiteralParserToken stringToken = m_lexer.currentToken();
+ m_lexer.next();
+ return jsString(m_exec, UString(stringToken.start + 1, stringToken.end - stringToken.start - 2));
+ }
+ case TokNumber: {
+ Lexer::LiteralParserToken numberToken = m_lexer.currentToken();
+ m_lexer.next();
+ return jsNumber(m_exec, UString(numberToken.start, numberToken.end - numberToken.start).toDouble());
+ }
+ default:
+ return JSValue();
+ }
+}
+
+JSValue LiteralParser::parseArray()
+{
+ StackGuard guard(this);
+ if (!guard.isSafe())
+ return abortParse();
+ JSArray* array = constructEmptyArray(m_exec);
+ while (true) {
+ m_lexer.next();
+ JSValue value = parseExpression();
+ if (m_aborted)
+ return JSValue();
+ if (!value)
+ break;
+ array->push(m_exec, value);
+
+ if (m_lexer.currentToken().type != TokComma)
+ break;
+ }
+ if (m_lexer.currentToken().type != TokRBracket)
+ return abortParse();
+
+ m_lexer.next();
+ return array;
+}
+
+JSValue LiteralParser::parseObject()
+{
+ StackGuard guard(this);
+ if (!guard.isSafe())
+ return abortParse();
+ JSObject* object = constructEmptyObject(m_exec);
+
+ while (m_lexer.next() == TokString) {
+ Lexer::LiteralParserToken identifierToken = m_lexer.currentToken();
+
+ // Check for colon
+ if (m_lexer.next() != TokColon)
+ return abortParse();
+ m_lexer.next();
+
+ JSValue value = parseExpression();
+ if (!value || m_aborted)
+ return abortParse();
+
+ Identifier ident(m_exec, identifierToken.start + 1, identifierToken.end - identifierToken.start - 2);
+ object->putDirect(ident, value);
+
+ if (m_lexer.currentToken().type != TokComma)
+ break;
+ }
+
+ if (m_lexer.currentToken().type != TokRBrace)
+ return abortParse();
+ m_lexer.next();
+ return object;
+}
+
+}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.h b/src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.h
new file mode 100644
index 0000000..a72e3d0
--- /dev/null
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/LiteralParser.h
@@ -0,0 +1,112 @@
+/*
+ * 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:
+ LiteralParser(ExecState* exec, const UString& s)
+ : m_exec(exec)
+ , m_lexer(s)
+ , m_depth(0)
+ , m_aborted(false)
+ {
+ }
+
+ JSValue tryLiteralParse()
+ {
+ m_lexer.next();
+ JSValue result = parseStatement();
+ if (m_aborted || m_lexer.currentToken().type != TokEnd)
+ return JSValue();
+ return result;
+ }
+ private:
+
+ enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace,
+ TokString, TokIdentifier, TokNumber, TokColon,
+ TokLParen, TokRParen, TokComma, TokEnd, TokError };
+
+ class Lexer {
+ public:
+ struct LiteralParserToken {
+ TokenType type;
+ const UChar* start;
+ const UChar* end;
+ };
+ Lexer(const UString& s)
+ : m_string(s)
+ , 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&);
+ TokenType lexString(LiteralParserToken&);
+ TokenType lexNumber(LiteralParserToken&);
+ LiteralParserToken m_currentToken;
+ UString m_string;
+ const UChar* m_ptr;
+ const UChar* m_end;
+ };
+
+ class StackGuard;
+ JSValue parseStatement();
+ JSValue parseExpression();
+ JSValue parseArray();
+ JSValue parseObject();
+
+ JSValue abortParse()
+ {
+ m_aborted = true;
+ return JSValue();
+ }
+
+ ExecState* m_exec;
+ LiteralParser::Lexer m_lexer;
+ int m_depth;
+ bool m_aborted;
+ };
+}
+
+#endif
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.cpp
index 98133a8..8359ff7 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.cpp
@@ -20,25 +20,13 @@
#include "config.h"
#include "Lookup.h"
+#include "JSFunction.h"
#include "PrototypeFunction.h"
namespace JSC {
void HashTable::createTable(JSGlobalData* globalData) const
{
-#if ENABLE(PERFECT_HASH_SIZE)
- ASSERT(!table);
- HashEntry* entries = new HashEntry[hashSizeMask + 1];
- for (int i = 0; i <= hashSizeMask; ++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() & hashSizeMask;
- ASSERT(!entries[hashIndex].key());
- entries[hashIndex].initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
- }
- table = entries;
-#else
ASSERT(!table);
int linkIndex = compactHashSizeMask + 1;
HashEntry* entries = new HashEntry[compactSize];
@@ -61,17 +49,12 @@ void HashTable::createTable(JSGlobalData* globalData) const
entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
}
table = entries;
-#endif
}
void HashTable::deleteTable() const
{
if (table) {
-#if ENABLE(PERFECT_HASH_SIZE)
- int max = hashSizeMask + 1;
-#else
int max = compactSize;
-#endif
for (int i = 0; i != max; ++i) {
if (UString::Rep* key = table[i].key())
key->deref();
@@ -84,11 +67,12 @@ void HashTable::deleteTable() const
void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
{
ASSERT(entry->attributes() & Function);
- JSValuePtr* location = thisObj->getDirectLocation(propertyName);
+ JSValue* location = thisObj->getDirectLocation(propertyName);
if (!location) {
- PrototypeFunction* function = new (exec) PrototypeFunction(exec, entry->functionLength(), propertyName, entry->function());
- thisObj->putDirect(propertyName, function, entry->attributes());
+ InternalFunction* function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
+
+ thisObj->putDirectFunction(propertyName, function, entry->attributes());
location = thisObj->getDirectLocation(propertyName);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.h
index 55c3221..3b7353d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Lookup.h
@@ -23,17 +23,12 @@
#include "CallFrame.h"
#include "Identifier.h"
-#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "PropertySlot.h"
#include <stdio.h>
#include <wtf/Assertions.h>
-// Set ENABLE_PERFECT_HASH_SIZE to 0 to save memory at the
-// cost of speed. Test your platform as results may vary.
-#define ENABLE_PERFECT_HASH_SIZE 1
-
namespace JSC {
// Hash table generated by the create_hash_table script.
@@ -45,9 +40,9 @@ namespace JSC {
};
// FIXME: There is no reason this get function can't be simpler.
- // ie. typedef JSValuePtr (*GetFunction)(ExecState*, JSObject* baseObject)
+ // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
typedef PropertySlot::GetValueFunc GetFunction;
- typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValuePtr value);
+ typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue value);
class HashEntry {
public:
@@ -57,9 +52,7 @@ namespace JSC {
m_attributes = attributes;
m_u.store.value1 = v1;
m_u.store.value2 = v2;
-#if !ENABLE(PERFECT_HASH_SIZE)
m_next = 0;
-#endif
}
void setKey(UString::Rep* key) { m_key = key; }
@@ -75,10 +68,8 @@ namespace JSC {
intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
-#if !ENABLE(PERFECT_HASH_SIZE)
void setNext(HashEntry *next) { m_next = next; }
HashEntry* next() const { return m_next; }
-#endif
private:
UString::Rep* m_key;
@@ -103,18 +94,14 @@ namespace JSC {
} lexer;
} m_u;
-#if !ENABLE(PERFECT_HASH_SIZE)
HashEntry* m_next;
-#endif
};
struct HashTable {
-#if ENABLE(PERFECT_HASH_SIZE)
- int hashSizeMask; // Precomputed size for the hash table (minus 1).
-#else
+
int compactSize;
int compactHashSizeMask;
-#endif
+
const HashTableValue* values; // Fixed values generated by script.
mutable const HashEntry* table; // Table allocated at runtime.
@@ -148,13 +135,6 @@ namespace JSC {
private:
ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
{
-#if ENABLE(PERFECT_HASH_SIZE)
- ASSERT(table);
- const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];
- if (entry->key() != identifier.ustring().rep())
- return 0;
- return entry;
-#else
ASSERT(table);
const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];
@@ -169,7 +149,6 @@ namespace JSC {
} while (entry);
return 0;
-#endif
}
// Convert the hash table keys to identifiers.
@@ -243,16 +222,19 @@ namespace JSC {
* is found it sets the value and returns true, else it returns false.
*/
template <class ThisImp>
- inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj)
+ 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
- thisObj->putDirect(propertyName, value);
- else if (!(entry->attributes() & ReadOnly))
+ 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;
@@ -265,7 +247,7 @@ namespace JSC {
* then it calls put() on the ParentImp class.
*/
template <class ThisImp, class ParentImp>
- inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
+ 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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.cpp
index 5bec2e6..2572bc9 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.cpp
@@ -27,29 +27,30 @@
#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 JSValuePtr mathProtoFuncAbs(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncACos(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncASin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncATan(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncATan2(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncCeil(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncCos(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncExp(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncFloor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncLog(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncMax(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncMin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncPow(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncRandom(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncRound(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncSin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncSqrt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncTan(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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&);
}
@@ -95,6 +96,7 @@ MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> structure)
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
@@ -113,62 +115,62 @@ bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
// ------------------------------ Functions --------------------------------
-JSValuePtr mathProtoFuncAbs(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, fabs(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, fabs(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncACos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, acos(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, acos(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncASin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, asin(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, asin(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncATan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, atan(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, atan(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncATan2(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, atan2(args.at(exec, 0)->toNumber(exec), args.at(exec, 1)->toNumber(exec)));
+ return jsNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
}
-JSValuePtr mathProtoFuncCeil(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, ceil(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, ceil(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncCos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, cos(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, cos(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncExp(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, exp(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, exp(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncFloor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, floor(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, floor(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncLog(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, log(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, log(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncMax(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+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(exec, k)->toNumber(exec);
+ double val = args.at(k).toNumber(exec);
if (isnan(val)) {
result = NaN;
break;
@@ -179,12 +181,12 @@ JSValuePtr mathProtoFuncMax(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
return jsNumber(exec, result);
}
-JSValuePtr mathProtoFuncMin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+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(exec, k)->toNumber(exec);
+ double val = args.at(k).toNumber(exec);
if (isnan(val)) {
result = NaN;
break;
@@ -195,12 +197,12 @@ JSValuePtr mathProtoFuncMin(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
return jsNumber(exec, result);
}
-JSValuePtr mathProtoFuncPow(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
// ECMA 15.8.2.1.13
- double arg = args.at(exec, 0)->toNumber(exec);
- double arg2 = args.at(exec, 1)->toNumber(exec);
+ double arg = args.at(0).toNumber(exec);
+ double arg2 = args.at(1).toNumber(exec);
if (isnan(arg2))
return jsNaN(exec);
@@ -209,32 +211,32 @@ JSValuePtr mathProtoFuncPow(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
return jsNumber(exec, pow(arg, arg2));
}
-JSValuePtr mathProtoFuncRandom(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
- return jsNumber(exec, WTF::randomNumber());
+ return jsNumber(exec, WTF::weakRandomNumber());
}
-JSValuePtr mathProtoFuncRound(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- double arg = args.at(exec, 0)->toNumber(exec);
+ 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));
}
-JSValuePtr mathProtoFuncSin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, sin(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, sin(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, sqrt(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, sqrt(args.at(0).toNumber(exec)));
}
-JSValuePtr mathProtoFuncTan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, tan(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, tan(args.at(0).toNumber(exec)));
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h
index d6163fd..3557d1e 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MathObject.h
@@ -34,7 +34,7 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 3d043e9..0205fc5 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -33,7 +33,7 @@ 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()))
+ : 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
@@ -43,8 +43,8 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<Struc
ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
{
ErrorInstance* object = new (exec) ErrorInstance(m_errorStructure);
- if (!args.at(exec, 0)->isUndefined())
- object->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0)->toString(exec)));
+ if (!args.at(0).isUndefined())
+ object->putDirect(exec->propertyNames().message, jsString(exec, args.at(0).toString(exec)));
return object;
}
@@ -58,8 +58,8 @@ ConstructType NativeErrorConstructor::getConstructData(ConstructData& constructD
constructData.native.function = constructWithNativeErrorConstructor;
return ConstructTypeHost;
}
-
-static JSValuePtr callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValuePtr, const ArgList& args)
+
+static JSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValue, const ArgList& args)
{
return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/NativeFunctionWrapper.h
index 4b88fd6..d4eeb3b 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ByteArray.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NativeFunctionWrapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ * 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
@@ -20,19 +20,20 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "ByteArray.h"
+#ifndef NativeFunctionWrapper_h
+#define NativeFunctionWrapper_h
namespace JSC {
-
-PassRefPtr<ByteArray> ByteArray::create(size_t size)
-{
- unsigned char* buffer = new unsigned char[size + sizeof(ByteArray) - sizeof(size_t)];
- ASSERT((reinterpret_cast<size_t>(buffer) & 3) == 0);
- return adoptRef(new (buffer) ByteArray(size));
+#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/webkit/JavaScriptCore/runtime/NumberConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.cpp
index 0da4d69..2840bf0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -29,11 +29,11 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
-static JSValuePtr numberConstructorNaNValue(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorNegInfinity(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorPosInfinity(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorMaxValue(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorMinValue(ExecState*, const Identifier&, const PropertySlot&);
+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
@@ -68,36 +68,36 @@ bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
}
-JSValuePtr numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNaN(exec);
}
-JSValuePtr numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, -Inf);
+ return jsNumber(exec, -Inf);
}
-JSValuePtr numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, Inf);
+ return jsNumber(exec, Inf);
}
-JSValuePtr numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, 1.7976931348623157E+308);
+ return jsNumber(exec, 1.7976931348623157E+308);
}
-JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, 5E-324);
+ 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(exec, 0)->toNumber(exec);
+ double n = args.isEmpty() ? 0 : args.at(0).toNumber(exec);
object->setInternalValue(jsNumber(exec, n));
return object;
}
@@ -109,9 +109,9 @@ ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.7.2
-static JSValuePtr callNumberConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callNumberConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, args.isEmpty() ? 0 : args.at(exec, 0)->toNumber(exec));
+ return jsNumber(exec, args.isEmpty() ? 0 : args.at(0).toNumber(exec));
}
CallType NumberConstructor::getCallData(CallData& callData)
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h
index 070be5f..b1224ec 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberConstructor.h
@@ -32,11 +32,11 @@ namespace JSC {
NumberConstructor(ExecState*, PassRefPtr<Structure>, NumberPrototype*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- JSValuePtr getValueProperty(ExecState*, int token) const;
+ JSValue getValueProperty(ExecState*, int token) const;
static const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValuePtr proto)
+ static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance));
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.cpp
index 6613390..0e8df17 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.cpp
@@ -36,23 +36,16 @@ NumberObject::NumberObject(PassRefPtr<Structure> structure)
{
}
-JSValuePtr NumberObject::getJSNumber()
+JSValue NumberObject::getJSNumber()
{
return internalValue();
}
-NumberObject* constructNumber(ExecState* exec, JSNumberCell* number)
+NumberObject* constructNumber(ExecState* exec, JSValue number)
{
NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
object->setInternalValue(number);
return object;
}
-NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValuePtr value)
-{
- NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
- object->setInternalValue(value);
- return object;
-}
-
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h
index 8cc2715..d354b9b 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberObject.h
@@ -25,8 +25,6 @@
namespace JSC {
- class JSNumberCell;
-
class NumberObject : public JSWrapperObject {
public:
explicit NumberObject(PassRefPtr<Structure>);
@@ -36,11 +34,10 @@ namespace JSC {
private:
virtual const ClassInfo* classInfo() const { return &info; }
- virtual JSValuePtr getJSNumber();
+ virtual JSValue getJSNumber();
};
- NumberObject* constructNumber(ExecState*, JSNumberCell*);
- NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValuePtr);
+ NumberObject* constructNumber(ExecState*, JSValue);
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberPrototype.cpp
index 8b45f54..947324c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -23,6 +23,7 @@
#include "NumberPrototype.h"
#include "Error.h"
+#include "JSFunction.h"
#include "JSString.h"
#include "PrototypeFunction.h"
#include "dtoa.h"
@@ -35,12 +36,12 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(NumberPrototype);
-static JSValuePtr numberProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToFixed(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToExponential(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToPrecision(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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
@@ -51,12 +52,12 @@ NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<Structure> structur
// The constructor will be added later, after NumberConstructor has been constructed
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
+ 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 ---------------------------
@@ -67,7 +68,8 @@ static UString integerPartNoExp(double d)
{
int decimalPoint;
int sign;
- char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
+ char result[80];
+ WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
bool resultIsInfOrNan = (decimalPoint == 9999);
size_t length = strlen(result);
@@ -80,17 +82,16 @@ static UString integerPartNoExp(double d)
Vector<char, 1024> buf(decimalPoint + 1);
if (static_cast<int>(length) <= decimalPoint) {
- strcpy(buf.data(), result);
+ 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());
}
- WTF::freedtoa(result);
-
return str;
}
@@ -133,15 +134,15 @@ static double intPow10(int e)
return static_cast<double>(result);
}
-JSValuePtr numberProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSValuePtr v = thisValue->getJSNumber();
+ JSValue v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- double radixAsDouble = args.at(exec, 0)->toInteger(exec); // nan -> 0
- if (radixAsDouble == 10 || args.at(exec, 0)->isUndefined())
- return jsString(exec, v->toString(exec));
+ 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");
@@ -153,7 +154,7 @@ JSValuePtr numberProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVa
// unless someone finds a precise rule.
char s[2048 + 3];
const char* lastCharInString = s + sizeof(s) - 1;
- double x = v->uncheckedGetNumber();
+ double x = v.uncheckedGetNumber();
if (isnan(x) || isinf(x))
return jsString(exec, UString::from(x));
@@ -197,39 +198,39 @@ JSValuePtr numberProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVa
return jsString(exec, startOfResultString);
}
-JSValuePtr numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
// FIXME: Not implemented yet.
- JSValuePtr v = thisValue->getJSNumber();
+ JSValue v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- return jsString(exec, v->toString(exec));
+ return jsString(exec, v.toString(exec));
}
-JSValuePtr numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- JSValuePtr v = thisValue->getJSNumber();
+ JSValue v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
return v;
}
-JSValuePtr numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSValuePtr v = thisValue->getJSNumber();
+ JSValue v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- JSValuePtr fractionDigits = args.at(exec, 0);
- double df = fractionDigits->toInteger(exec);
+ 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();
+ double x = v.uncheckedGetNumber();
if (isnan(x))
return jsNontrivialString(exec, "NaN");
@@ -277,7 +278,8 @@ static void fractionalPartToString(char* buf, int& i, const char* result, int re
strncpy(buf + i, result + 1, fractionalDigits);
i += fractionalDigits;
} else {
- strcpy(buf + i, result + 1);
+ ASSERT(i + resultLength - 1 < 80);
+ memcpy(buf + i, result + 1, resultLength - 1);
i += static_cast<int>(resultLength) - 1;
}
}
@@ -302,23 +304,23 @@ static void exponentialPartToString(char* buf, int& i, int decimalPoint)
buf[i++] = static_cast<char>('0' + exponential % 10);
}
-JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSValuePtr v = thisValue->getJSNumber();
+ JSValue v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- double x = v->uncheckedGetNumber();
+ double x = v.uncheckedGetNumber();
if (isnan(x) || isinf(x))
return jsString(exec, UString::from(x));
- JSValuePtr fractionalDigitsValue = args.at(exec, 0);
- double df = fractionalDigitsValue->toInteger(exec);
+ 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();
+ bool includeAllDigits = fractionalDigitsValue.isUndefined();
int decimalAdjust = 0;
if (x && !includeAllDigits) {
@@ -344,7 +346,8 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
int decimalPoint;
int sign;
- char* result = WTF::dtoa(x, 0, &decimalPoint, &sign, NULL);
+ char result[80];
+ WTF::dtoa(result, x, 0, &decimalPoint, &sign, NULL);
size_t resultLength = strlen(result);
decimalPoint += decimalAdjust;
@@ -353,9 +356,12 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
if (sign)
buf[i++] = '-';
- if (decimalPoint == 999) // ? 9999 is the magical "result is Inf or NaN" value. what's 999??
- strcpy(buf + i, result);
- else {
+ // ? 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)
@@ -367,21 +373,19 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
}
ASSERT(i <= 80);
- WTF::freedtoa(result);
-
return jsString(exec, buf);
}
-JSValuePtr numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSValuePtr v = thisValue->getJSNumber();
+ JSValue v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- double doublePrecision = args.at(exec, 0)->toIntegerPreserveNaN(exec);
- double x = v->uncheckedGetNumber();
- if (args.at(exec, 0)->isUndefined() || isnan(x) || isinf(x))
- return jsString(exec, v->toString(exec));
+ 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) {
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp
index ff97ca4..cf1790f 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "ObjectConstructor.h"
+#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "ObjectPrototype.h"
@@ -41,10 +42,10 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> stru
// ECMA 15.2.2
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
{
- JSValuePtr arg = args.at(exec, 0);
- if (arg->isUndefinedOrNull())
+ JSValue arg = args.at(0);
+ if (arg.isUndefinedOrNull())
return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
- return arg->toObject(exec);
+ return arg.toObject(exec);
}
static JSObject* constructWithObjectConstructor(ExecState* exec, JSObject*, const ArgList& args)
@@ -58,7 +59,7 @@ ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
return ConstructTypeHost;
}
-static JSValuePtr callObjectConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
return constructObject(exec, args);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp
index 696570b..98e4713 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -22,6 +22,7 @@
#include "ObjectPrototype.h"
#include "Error.h"
+#include "JSFunction.h"
#include "JSString.h"
#include "PrototypeFunction.h"
@@ -29,58 +30,58 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
-static JSValuePtr objectProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
+ 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) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
+ 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
-JSValuePtr objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- return thisValue->toThisObject(exec);
+ return thisValue.toThisObject(exec);
}
-JSValuePtr objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- return jsBoolean(thisValue->toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(exec, 0)->toString(exec))));
+ return jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(0).toString(exec))));
}
-JSValuePtr objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- if (!args.at(exec, 0)->isObject())
+ if (!args.at(0).isObject())
return jsBoolean(false);
- JSValuePtr v = asObject(args.at(exec, 0))->prototype();
+ JSValue v = asObject(args.at(0))->prototype();
while (true) {
- if (!v->isObject())
+ if (!v.isObject())
return jsBoolean(false);
if (v == thisObj)
return jsBoolean(true);
@@ -88,47 +89,47 @@ JSValuePtr objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValuePtr t
}
}
-JSValuePtr objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
CallData callData;
- if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
+ if (args.at(1).getCallData(callData) == CallTypeNone)
return throwError(exec, SyntaxError, "invalid getter usage");
- thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
+ thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(0).toString(exec)), asObject(args.at(1)));
return jsUndefined();
}
-JSValuePtr objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
CallData callData;
- if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
+ if (args.at(1).getCallData(callData) == CallTypeNone)
return throwError(exec, SyntaxError, "invalid setter usage");
- thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
+ thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(0).toString(exec)), asObject(args.at(1)));
return jsUndefined();
}
-JSValuePtr objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- return thisValue->toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)));
+ return thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(0).toString(exec)));
}
-JSValuePtr objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- return thisValue->toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)));
+ return thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(0).toString(exec)));
}
-JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- return jsBoolean(thisValue->toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(exec, 0)->toString(exec))));
+ return jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(0).toString(exec))));
}
-JSValuePtr objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- return thisValue->toThisJSString(exec);
+ return thisValue.toThisJSString(exec);
}
-JSValuePtr objectProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- return jsNontrivialString(exec, "[object " + thisValue->toThisObject(exec)->className() + "]");
+ return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.h
index 1c432fe..7790ae0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ObjectPrototype.h
@@ -30,7 +30,7 @@ namespace JSC {
ObjectPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
- JSValuePtr objectProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.cpp
index 6f84303..093bbec 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.cpp
@@ -35,41 +35,87 @@
namespace JSC {
-// ECMA 11.9.3
-bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+bool JSValue::equalSlowCase(ExecState* exec, JSValue v1, JSValue v2)
{
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return v1 == v2;
-
return equalSlowCaseInline(exec, v1, v2);
}
-bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+bool JSValue::strictEqualSlowCase(JSValue v1, JSValue v2)
{
- return equalSlowCaseInline(exec, v1, v2);
+ return strictEqualSlowCaseInline(v1, v2);
}
-bool strictEqual(JSValuePtr v1, JSValuePtr v2)
+NEVER_INLINE JSValue throwOutOfMemoryError(ExecState* exec)
{
- if (JSImmediate::areBothImmediate(v1, v2))
- return v1 == v2;
+ JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+ exec->setException(error);
+ return error;
+}
- if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != JSImmediate::from(0)) & (v2 != JSImmediate::from(0)))
- return false;
+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);
- return strictEqualSlowCaseInline(v1, v2);
+ 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));
}
-bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2)
+JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
{
- return strictEqualSlowCaseInline(v1, v2);
+ 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");
}
-NEVER_INLINE JSValuePtr throwOutOfMemoryError(ExecState* exec)
+bool jsIsObjectType(JSValue v)
{
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
- return error;
+ 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/webkit/JavaScriptCore/runtime/Operations.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h
index f627c52..acfc6c2 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Operations.h
@@ -22,116 +22,313 @@
#ifndef Operations_h
#define Operations_h
+#include "Interpreter.h"
#include "JSImmediate.h"
#include "JSNumberCell.h"
#include "JSString.h"
namespace JSC {
- // ECMA 11.9.3
- bool equal(ExecState*, JSValuePtr, JSValuePtr);
- bool equalSlowCase(ExecState*, JSValuePtr, JSValuePtr);
-
- ALWAYS_INLINE bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(!JSImmediate::areBothImmediateNumbers(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;
- JSValuePtr p1 = v1->toPrimitive(exec);
- if (exec->hadException())
- return false;
- v1 = p1;
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return v1 == v2;
- continue;
- }
-
- if (v2->isObject()) {
- JSValuePtr p2 = v2->toPrimitive(exec);
- if (exec->hadException())
- return false;
- v2 = p2;
- if (JSImmediate::areBothImmediateNumbers(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);
- }
-
-
- bool strictEqual(JSValuePtr, JSValuePtr);
- bool strictEqualSlowCase(JSValuePtr, JSValuePtr);
-
- inline bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2)
- {
- ASSERT(!JSImmediate::areBothImmediate(v1, v2));
-
- if (JSImmediate::isEitherImmediate(v1, v2)) {
- ASSERT(v1 == JSImmediate::zeroImmediate() || v2 == JSImmediate::zeroImmediate());
- ASSERT(v1 != v2);
-
- // The reason we can't just return false here is that 0 === -0,
- // and while the former is an immediate number, the latter is not.
- if (v1 == JSImmediate::zeroImmediate())
- return asCell(v2)->isNumber() && asNumberCell(v2)->value() == 0;
- return asCell(v1)->isNumber() && asNumberCell(v1)->value() == 0;
- }
-
- if (asCell(v1)->isNumber()) {
- return asCell(v2)->isNumber()
- && asNumberCell(v1)->value() == asNumberCell(v2)->value();
- }
-
- if (asCell(v1)->isString()) {
- return asCell(v2)->isString()
- && asString(v1)->value() == asString(v2)->value();
- }
-
- return v1 == v2;
- }
-
- JSValuePtr throwOutOfMemoryError(ExecState*);
-}
-
-#endif
+ 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/webkit/JavaScriptCore/runtime/PropertyMapHashTable.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyMapHashTable.h
index 935df68..44dc2b8 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -30,20 +30,23 @@ namespace JSC {
UString::Rep* key;
unsigned offset;
unsigned attributes;
+ JSCell* specificValue;
unsigned index;
- PropertyMapEntry(UString::Rep* key, unsigned attributes)
+ 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, unsigned index)
+ PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index)
: key(key)
, offset(offset)
, attributes(attributes)
+ , specificValue(specificValue)
, index(index)
{
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp
index 47e9d84..0878e73 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -27,7 +27,7 @@ static const size_t setThreshold = 20;
void PropertyNameArray::add(UString::Rep* identifier)
{
- ASSERT(identifier == &UString::Rep::null || identifier == &UString::Rep::empty || identifier->identifierTable());
+ ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->identifierTable());
size_t size = m_data->propertyNameVector().size();
if (size < setThreshold) {
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h
index 7dc14fe..b4382f4 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertyNameArray.h
@@ -65,14 +65,14 @@ namespace JSC {
PropertyNameArray(JSGlobalData* globalData)
: m_data(PropertyNameArrayData::create())
, m_globalData(globalData)
- , m_cacheable(true)
+ , m_shouldCache(true)
{
}
PropertyNameArray(ExecState* exec)
: m_data(PropertyNameArrayData::create())
, m_globalData(&exec->globalData())
- , m_cacheable(true)
+ , m_shouldCache(true)
{
}
@@ -95,8 +95,8 @@ namespace JSC {
PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); }
- void setCacheable(bool cacheable) { m_cacheable = cacheable; }
- bool cacheable() const { return m_cacheable; }
+ void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; }
+ bool shouldCache() const { return m_shouldCache; }
private:
typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
@@ -104,7 +104,7 @@ namespace JSC {
RefPtr<PropertyNameArrayData> m_data;
IdentifierSet m_set;
JSGlobalData* m_globalData;
- bool m_cacheable;
+ bool m_shouldCache;
};
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp
index 175f271..36fa5d8 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.cpp
@@ -27,7 +27,7 @@
namespace JSC {
-JSValuePtr PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
// Prevent getter functions from observing execution if an exception is pending.
if (exec->hadException())
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.h
index 1dd1afa..7af60ce 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PropertySlot.h
@@ -45,30 +45,30 @@ namespace JSC {
clearValue();
}
- explicit PropertySlot(const JSValuePtr base)
+ explicit PropertySlot(const JSValue base)
: m_slotBase(base)
, m_offset(WTF::notFound)
{
clearValue();
}
- typedef JSValuePtr (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
+ typedef JSValue (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
- JSValuePtr getValue(ExecState* exec, const Identifier& propertyName) const
+ JSValue getValue(ExecState* exec, const Identifier& propertyName) const
{
if (m_getValue == JSC_VALUE_SLOT_MARKER)
return *m_data.valueSlot;
if (m_getValue == JSC_REGISTER_SLOT_MARKER)
- return (*m_data.registerSlot).jsValue(exec);
+ return (*m_data.registerSlot).jsValue();
return m_getValue(exec, propertyName, *this);
}
- JSValuePtr getValue(ExecState* exec, unsigned propertyName) const
+ JSValue getValue(ExecState* exec, unsigned propertyName) const
{
if (m_getValue == JSC_VALUE_SLOT_MARKER)
return *m_data.valueSlot;
if (m_getValue == JSC_REGISTER_SLOT_MARKER)
- return (*m_data.registerSlot).jsValue(exec);
+ return (*m_data.registerSlot).jsValue();
return m_getValue(exec, Identifier::from(exec, propertyName), *this);
}
@@ -79,17 +79,17 @@ namespace JSC {
return m_offset;
}
- void putValue(JSValuePtr value)
+ void putValue(JSValue value)
{
if (m_getValue == JSC_VALUE_SLOT_MARKER) {
*m_data.valueSlot = value;
return;
}
ASSERT(m_getValue == JSC_REGISTER_SLOT_MARKER);
- *m_data.registerSlot = JSValuePtr(value);
+ *m_data.registerSlot = JSValue(value);
}
- void setValueSlot(JSValuePtr* valueSlot)
+ void setValueSlot(JSValue* valueSlot)
{
ASSERT(valueSlot);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -97,7 +97,7 @@ namespace JSC {
m_data.valueSlot = valueSlot;
}
- void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot)
+ void setValueSlot(JSValue slotBase, JSValue* valueSlot)
{
ASSERT(valueSlot);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -105,7 +105,7 @@ namespace JSC {
m_data.valueSlot = valueSlot;
}
- void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot, size_t offset)
+ void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset)
{
ASSERT(valueSlot);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -114,7 +114,7 @@ namespace JSC {
m_offset = offset;
}
- void setValue(JSValuePtr value)
+ void setValue(JSValue value)
{
ASSERT(value);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -131,7 +131,7 @@ namespace JSC {
m_data.registerSlot = registerSlot;
}
- void setCustom(JSValuePtr slotBase, GetValueFunc getValue)
+ void setCustom(JSValue slotBase, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
@@ -139,7 +139,7 @@ namespace JSC {
m_slotBase = slotBase;
}
- void setCustomIndex(JSValuePtr slotBase, unsigned index, GetValueFunc getValue)
+ void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
@@ -161,13 +161,13 @@ namespace JSC {
setValue(jsUndefined());
}
- JSValuePtr slotBase() const
+ JSValue slotBase() const
{
ASSERT(m_slotBase);
return m_slotBase;
}
- void setBase(JSValuePtr base)
+ void setBase(JSValue base)
{
ASSERT(m_slotBase);
ASSERT(base);
@@ -177,33 +177,33 @@ namespace JSC {
void clearBase()
{
#ifndef NDEBUG
- m_slotBase = noValue();
+ m_slotBase = JSValue();
#endif
}
void clearValue()
{
#ifndef NDEBUG
- m_value = noValue();
+ m_value = JSValue();
#endif
}
unsigned index() const { return m_data.index; }
private:
- static JSValuePtr functionGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&);
GetValueFunc m_getValue;
- JSValuePtr m_slotBase;
+ JSValue m_slotBase;
union {
JSObject* getterFunc;
- JSValuePtr* valueSlot;
+ JSValue* valueSlot;
Register* registerSlot;
unsigned index;
} m_data;
- JSValuePtr m_value;
+ JSValue m_value;
size_t m_offset;
};
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h
index efbc4bb..224164d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Protect.h
@@ -49,18 +49,16 @@ namespace JSC {
gcUnprotect(val);
}
- inline void gcProtect(JSValuePtr value)
+ inline void gcProtect(JSValue value)
{
- if (!value || JSImmediate::isImmediate(value))
- return;
- gcProtect(asCell(value));
+ if (value && value.isCell())
+ gcProtect(asCell(value));
}
- inline void gcUnprotect(JSValuePtr value)
+ inline void gcUnprotect(JSValue value)
{
- if (!value || JSImmediate::isImmediate(value))
- return;
- gcUnprotect(asCell(value));
+ if (value && value.isCell())
+ gcUnprotect(asCell(value));
}
// FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
@@ -76,7 +74,7 @@ namespace JSC {
T* get() const { return m_ptr; }
operator T*() const { return m_ptr; }
- operator JSValuePtr() const { return JSValuePtr(m_ptr); }
+ operator JSValue() const { return JSValue(m_ptr); }
T* operator->() const { return m_ptr; }
operator bool() const { return m_ptr; }
@@ -89,27 +87,27 @@ namespace JSC {
T* m_ptr;
};
- class ProtectedJSValuePtr {
+ class ProtectedJSValue {
public:
- ProtectedJSValuePtr() {}
- ProtectedJSValuePtr(JSValuePtr value);
- ProtectedJSValuePtr(const ProtectedJSValuePtr&);
- ~ProtectedJSValuePtr();
+ ProtectedJSValue() {}
+ ProtectedJSValue(JSValue value);
+ ProtectedJSValue(const ProtectedJSValue&);
+ ~ProtectedJSValue();
- template <class U> ProtectedJSValuePtr(const ProtectedPtr<U>&);
+ template <class U> ProtectedJSValue(const ProtectedPtr<U>&);
- JSValuePtr get() const { return m_value; }
- operator JSValuePtr() const { return m_value; }
- JSValuePtr operator->() const { return m_value; }
+ 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; }
- ProtectedJSValuePtr& operator=(const ProtectedJSValuePtr&);
- ProtectedJSValuePtr& operator=(JSValuePtr);
+ ProtectedJSValue& operator=(const ProtectedJSValue&);
+ ProtectedJSValue& operator=(JSValue);
private:
- JSValuePtr m_value;
+ JSValue m_value;
};
template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr)
@@ -152,39 +150,39 @@ namespace JSC {
return *this;
}
- inline ProtectedJSValuePtr::ProtectedJSValuePtr(JSValuePtr value)
+ inline ProtectedJSValue::ProtectedJSValue(JSValue value)
: m_value(value)
{
gcProtect(m_value);
}
- inline ProtectedJSValuePtr::ProtectedJSValuePtr(const ProtectedJSValuePtr& o)
+ inline ProtectedJSValue::ProtectedJSValue(const ProtectedJSValue& o)
: m_value(o.get())
{
gcProtect(m_value);
}
- inline ProtectedJSValuePtr::~ProtectedJSValuePtr()
+ inline ProtectedJSValue::~ProtectedJSValue()
{
gcUnprotect(m_value);
}
- template <class U> ProtectedJSValuePtr::ProtectedJSValuePtr(const ProtectedPtr<U>& o)
+ template <class U> ProtectedJSValue::ProtectedJSValue(const ProtectedPtr<U>& o)
: m_value(o.get())
{
gcProtect(m_value);
}
- inline ProtectedJSValuePtr& ProtectedJSValuePtr::operator=(const ProtectedJSValuePtr& o)
+ inline ProtectedJSValue& ProtectedJSValue::operator=(const ProtectedJSValue& o)
{
- JSValuePtr ovalue = o.m_value;
+ JSValue ovalue = o.m_value;
gcProtect(ovalue);
gcUnprotect(m_value);
m_value = ovalue;
return *this;
}
- inline ProtectedJSValuePtr& ProtectedJSValuePtr::operator=(JSValuePtr ovalue)
+ inline ProtectedJSValue& ProtectedJSValue::operator=(JSValue ovalue)
{
gcProtect(ovalue);
gcUnprotect(m_value);
@@ -200,17 +198,17 @@ namespace JSC {
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 ProtectedJSValuePtr& a, const ProtectedJSValuePtr& b) { return a.get() == b.get(); }
- inline bool operator==(const ProtectedJSValuePtr& a, const JSValuePtr b) { return a.get() == b; }
- template <class T> inline bool operator==(const ProtectedJSValuePtr& a, const ProtectedPtr<T>& b) { return a.get() == JSValuePtr(b.get()); }
- inline bool operator==(const JSValuePtr a, const ProtectedJSValuePtr& b) { return a == b.get(); }
- template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValuePtr& b) { return JSValuePtr(a.get()) == b.get(); }
-
- inline bool operator!=(const ProtectedJSValuePtr& a, const ProtectedJSValuePtr& b) { return a.get() != b.get(); }
- inline bool operator!=(const ProtectedJSValuePtr& a, const JSValuePtr b) { return a.get() != b; }
- template <class T> inline bool operator!=(const ProtectedJSValuePtr& a, const ProtectedPtr<T>& b) { return a.get() != JSValuePtr(b.get()); }
- inline bool operator!=(const JSValuePtr a, const ProtectedJSValuePtr& b) { return a != b.get(); }
- template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValuePtr& b) { return JSValuePtr(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(); }
+
+ 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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/PutPropertySlot.h b/src/3rdparty/webkit/JavaScriptCore/runtime/PutPropertySlot.h
index 1e2dfe9..eb8ea8a 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/PutPropertySlot.h
@@ -32,15 +32,15 @@
namespace JSC {
class JSObject;
+ class JSFunction;
class PutPropertySlot {
public:
- enum Type { Invalid, ExistingProperty, NewProperty };
+ enum Type { Uncachable, ExistingProperty, NewProperty };
PutPropertySlot()
- : m_type(Invalid)
+ : m_type(Uncachable)
, m_base(0)
- , m_wasTransition(false)
{
}
@@ -61,18 +61,14 @@ namespace JSC {
Type type() const { return m_type; }
JSObject* base() const { return m_base; }
- bool isCacheable() const { return m_type != Invalid; }
+ bool isCacheable() const { return m_type != Uncachable; }
size_t cachedOffset() const {
ASSERT(isCacheable());
return m_offset;
}
-
- bool wasTransition() const { return m_wasTransition; }
- void setWasTransition(bool wasTransition) { m_wasTransition = wasTransition; }
private:
Type m_type;
JSObject* m_base;
- bool m_wasTransition;
size_t m_offset;
};
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.cpp
index 722914d8..857a316 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.cpp
@@ -20,17 +20,33 @@
#include "config.h"
#include "RegExp.h"
-
-#include "JIT.h"
#include "Lexer.h"
-#include "WRECGenerator.h"
-#include <pcre/pcre.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)
@@ -40,62 +56,41 @@ using namespace WREC;
inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
: m_pattern(pattern)
, m_flagBits(0)
- , m_regExp(0)
, m_constructionError(0)
, m_numSubpatterns(0)
{
- UNUSED_PARAM(globalData);
-#if ENABLE(WREC)
- m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool);
- if (m_wrecFunction || m_constructionError)
- return;
- // Fall through to non-WREC case.
-#endif
- m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
- JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
-}
-
-PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
-{
- return adoptRef(new RegExp(globalData, pattern));
+ compile(globalData);
}
inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
: m_pattern(pattern)
, m_flags(flags)
, m_flagBits(0)
- , m_regExp(0)
, m_constructionError(0)
, m_numSubpatterns(0)
{
- UNUSED_PARAM(globalData);
-
// NOTE: The global flag is handled on a case-by-case basis by functions like
// String::match and RegExpObject::match.
if (flags.find('g') != -1)
m_flagBits |= Global;
-
- // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
- JSRegExpIgnoreCaseOption ignoreCaseOption = JSRegExpDoNotIgnoreCase;
- if (flags.find('i') != -1) {
+ if (flags.find('i') != -1)
m_flagBits |= IgnoreCase;
- ignoreCaseOption = JSRegExpIgnoreCase;
- }
-
- JSRegExpMultilineOption multilineOption = JSRegExpSingleLine;
- if (flags.find('m') != -1) {
+ if (flags.find('m') != -1)
m_flagBits |= Multiline;
- multilineOption = JSRegExpMultiline;
- }
-#if ENABLE(WREC)
- m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
- if (m_wrecFunction || m_constructionError)
- return;
- // Fall through to non-WREC case.
+ compile(globalData);
+}
+
+#if !ENABLE(YARR)
+RegExp::~RegExp()
+{
+ jsRegExpFree(m_regExp);
+}
#endif
- m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
- ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
+
+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)
@@ -103,9 +98,83 @@ PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patte
return adoptRef(new RegExp(globalData, pattern, flags));
}
-RegExp::~RegExp()
+#if ENABLE(YARR)
+
+void RegExp::compile(JSGlobalData* globalData)
{
- jsRegExpFree(m_regExp);
+#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, OwnArrayPtr<int>* 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 = new int [offsetVectorSize];
+ ASSERT(offsetVector);
+ for (int j = 0; j < offsetVectorSize; ++j)
+ offsetVector[j] = -1;
+
+ OwnArrayPtr<int> nonReturnedOvector;
+ if (!ovector)
+ nonReturnedOvector.set(offsetVector);
+ else
+ ovector->set(offsetVector);
+
+#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, OwnArrayPtr<int>* ovector)
@@ -122,6 +191,7 @@ int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
if (m_wrecFunction) {
int offsetVectorSize = (m_numSubpatterns + 1) * 2;
int* offsetVector = new int [offsetVectorSize];
+ ASSERT(offsetVector);
for (int j = 0; j < offsetVectorSize; ++j)
offsetVector[j] = -1;
@@ -178,4 +248,6 @@ int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
return -1;
}
+#endif
+
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.h
index 139c754..f3be656 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExp.h
@@ -26,6 +26,8 @@
#include "ExecutableAllocator.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+#include "yarr/RegexJIT.h"
+#include "yarr/RegexInterpreter.h"
struct JSRegExp;
@@ -37,7 +39,9 @@ namespace JSC {
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; }
@@ -56,21 +60,27 @@ namespace JSC {
RegExp(JSGlobalData* globalData, const UString& pattern);
RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
- void compile();
+ 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;
- JSRegExp* m_regExp;
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
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp
index 84a297c..bcd0d07 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -33,24 +33,24 @@
namespace JSC {
-static JSValuePtr regExpConstructorInput(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorLastMatch(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorLastParen(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorLeftContext(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorRightContext(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar1(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar2(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar3(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar4(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar5(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar6(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar7(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar8(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar9(ExecState*, const Identifier&, const PropertySlot&);
-
-static void setRegExpConstructorInput(ExecState*, JSObject*, JSValuePtr);
-static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValuePtr);
+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
@@ -185,7 +185,7 @@ JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
return new (exec) RegExpMatchesArray(exec, d.get());
}
-JSValuePtr RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
+JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
{
if (d->lastOvector && i <= d->lastNumSubPatterns) {
int start = d->lastOvector[2 * i];
@@ -195,7 +195,7 @@ JSValuePtr RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
return jsEmptyString(exec);
}
-JSValuePtr RegExpConstructor::getLastParen(ExecState* exec) const
+JSValue RegExpConstructor::getLastParen(ExecState* exec) const
{
unsigned i = d->lastNumSubPatterns;
if (i > 0) {
@@ -207,14 +207,14 @@ JSValuePtr RegExpConstructor::getLastParen(ExecState* exec) const
return jsEmptyString(exec);
}
-JSValuePtr RegExpConstructor::getLeftContext(ExecState* exec) const
+JSValue RegExpConstructor::getLeftContext(ExecState* exec) const
{
if (d->lastOvector)
return jsSubstring(exec, d->lastInput, 0, d->lastOvector[0]);
return jsEmptyString(exec);
}
-JSValuePtr RegExpConstructor::getRightContext(ExecState* exec) const
+JSValue RegExpConstructor::getRightContext(ExecState* exec) const
{
if (d->lastOvector)
return jsSubstring(exec, d->lastInput, d->lastOvector[1], d->lastInput.size() - d->lastOvector[1]);
@@ -226,110 +226,110 @@ bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot);
}
-JSValuePtr regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1);
}
-JSValuePtr regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 2);
}
-JSValuePtr regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 3);
}
-JSValuePtr regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 4);
}
-JSValuePtr regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 5);
}
-JSValuePtr regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 6);
}
-JSValuePtr regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 7);
}
-JSValuePtr regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 8);
}
-JSValuePtr regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 9);
}
-JSValuePtr regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsString(exec, asRegExpConstructor(slot.slotBase())->input());
}
-JSValuePtr regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpConstructor(slot.slotBase())->multiline());
}
-JSValuePtr regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 0);
}
-JSValuePtr regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getLastParen(exec);
}
-JSValuePtr regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getLeftContext(exec);
}
-JSValuePtr regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getRightContext(exec);
}
-void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+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, JSValuePtr value)
+void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpConstructor(baseObject)->setInput(value->toString(exec));
+ asRegExpConstructor(baseObject)->setInput(value.toString(exec));
}
-void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValuePtr value)
+void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpConstructor(baseObject)->setMultiline(value->toBoolean(exec));
+ asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
}
// ECMA 15.10.4
JSObject* constructRegExp(ExecState* exec, const ArgList& args)
{
- JSValuePtr arg0 = args.at(exec, 0);
- JSValuePtr arg1 = args.at(exec, 1);
+ JSValue arg0 = args.at(0);
+ JSValue arg1 = args.at(1);
- if (arg0->isObject(&RegExpObject::info)) {
- if (!arg1->isUndefined())
+ 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);
+ 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())
@@ -349,7 +349,7 @@ ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.10.3
-static JSValuePtr callRegExpConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
return constructRegExp(exec, args);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h
index f8c4366..6823f3f 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpConstructor.h
@@ -34,12 +34,12 @@ namespace JSC {
public:
RegExpConstructor(ExecState*, PassRefPtr<Structure>, RegExpPrototype*);
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
}
- virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
static const ClassInfo info;
@@ -53,10 +53,10 @@ namespace JSC {
void setMultiline(bool);
bool multiline() const;
- JSValuePtr getBackref(ExecState*, unsigned) const;
- JSValuePtr getLastParen(ExecState*) const;
- JSValuePtr getLeftContext(ExecState*) const;
- JSValuePtr getRightContext(ExecState*) const;
+ JSValue getBackref(ExecState*, unsigned) const;
+ JSValue getLastParen(ExecState*) const;
+ JSValue getLeftContext(ExecState*) const;
+ JSValue getRightContext(ExecState*) const;
private:
virtual ConstructType getConstructData(ConstructData&);
@@ -67,11 +67,11 @@ namespace JSC {
OwnPtr<RegExpConstructorPrivate> d;
};
- RegExpConstructor* asRegExpConstructor(JSValuePtr);
+ RegExpConstructor* asRegExpConstructor(JSValue);
JSObject* constructRegExp(ExecState*, const ArgList&);
- inline RegExpConstructor* asRegExpConstructor(JSValuePtr value)
+ inline RegExpConstructor* asRegExpConstructor(JSValue value)
{
ASSERT(asObject(value)->inherits(&RegExpConstructor::info));
return static_cast<RegExpConstructor*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpMatchesArray.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpMatchesArray.h
index 3583941..9ae18b9 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -44,14 +44,14 @@ namespace JSC {
return JSArray::getOwnPropertySlot(exec, propertyName, slot);
}
- virtual void put(ExecState* exec, const Identifier& propertyName, JSValuePtr v, PutPropertySlot& 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, JSValuePtr v)
+ virtual void put(ExecState* exec, unsigned propertyName, JSValue v)
{
if (lazyCreationData())
fillArrayInstance(exec);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp
index 5a54ad0..687844e 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "RegExpObject.h"
+#include "Error.h"
#include "JSArray.h"
#include "JSGlobalObject.h"
#include "JSString.h"
@@ -29,12 +30,12 @@
namespace JSC {
-static JSValuePtr regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectSource(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectLastIndex(ExecState*, const Identifier&, const PropertySlot&);
-static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValuePtr);
+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
@@ -71,54 +72,54 @@ bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert
return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
}
-JSValuePtr regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
}
-JSValuePtr regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
}
-JSValuePtr regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
}
-JSValuePtr regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
}
-JSValuePtr regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
}
-void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+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, JSValuePtr value)
+void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
{
- asRegExpObject(baseObject)->setLastIndex(value->toInteger(exec));
+ asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
}
-JSValuePtr RegExpObject::test(ExecState* exec, const ArgList& args)
+JSValue RegExpObject::test(ExecState* exec, const ArgList& args)
{
return jsBoolean(match(exec, args));
}
-JSValuePtr RegExpObject::exec(ExecState* exec, const ArgList& args)
+JSValue RegExpObject::exec(ExecState* exec, const ArgList& args)
{
if (match(exec, args))
return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec);
return jsNull();
}
-static JSValuePtr callRegExpObject(ExecState* exec, JSObject* function, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callRegExpObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args)
{
return asRegExpObject(function)->exec(exec, args);
}
@@ -134,7 +135,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
{
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
- UString input = args.isEmpty() ? regExpConstructor->input() : args.at(exec, 0)->toString(exec);
+ UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
if (input.isNull()) {
throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
return false;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h
index 4c99c30..fac9978 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpObject.h
@@ -37,16 +37,16 @@ namespace JSC {
void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
double lastIndex() const { return d->lastIndex; }
- JSValuePtr test(ExecState*, const ArgList&);
- JSValuePtr exec(ExecState*, const ArgList&);
+ 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, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
@@ -70,9 +70,9 @@ namespace JSC {
OwnPtr<RegExpObjectData> d;
};
- RegExpObject* asRegExpObject(JSValuePtr);
+ RegExpObject* asRegExpObject(JSValue);
- inline RegExpObject* asRegExpObject(JSValuePtr value)
+ inline RegExpObject* asRegExpObject(JSValue value)
{
ASSERT(asObject(value)->inherits(&RegExpObject::info));
return static_cast<RegExpObject*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpPrototype.cpp
index b47d489..b1ab889 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -23,6 +23,7 @@
#include "ArrayPrototype.h"
#include "JSArray.h"
+#include "JSFunction.h"
#include "JSObject.h"
#include "JSString.h"
#include "JSValue.h"
@@ -35,10 +36,10 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype);
-static JSValuePtr regExpProtoFuncTest(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr regExpProtoFuncExec(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr regExpProtoFuncCompile(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr regExpProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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
@@ -47,44 +48,44 @@ const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: JSObject(structure)
{
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
+ 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 ---------------------------
-JSValuePtr regExpProtoFuncTest(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&RegExpObject::info))
+ if (!thisValue.isObject(&RegExpObject::info))
return throwError(exec, TypeError);
return asRegExpObject(thisValue)->test(exec, args);
}
-JSValuePtr regExpProtoFuncExec(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&RegExpObject::info))
+ if (!thisValue.isObject(&RegExpObject::info))
return throwError(exec, TypeError);
return asRegExpObject(thisValue)->exec(exec, args);
}
-JSValuePtr regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&RegExpObject::info))
+ if (!thisValue.isObject(&RegExpObject::info))
return throwError(exec, TypeError);
RefPtr<RegExp> regExp;
- JSValuePtr arg0 = args.at(exec, 0);
- JSValuePtr arg1 = args.at(exec, 1);
+ JSValue arg0 = args.at(0);
+ JSValue arg1 = args.at(1);
- if (arg0->isObject(&RegExpObject::info)) {
- if (!arg1->isUndefined())
+ 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);
+ UString pattern = args.isEmpty() ? UString("") : arg0.toString(exec);
+ UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
regExp = RegExp::create(&exec->globalData(), pattern, flags);
}
@@ -96,21 +97,21 @@ JSValuePtr regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValuePtr thisVal
return jsUndefined();
}
-JSValuePtr regExpProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- if (!thisValue->isObject(&RegExpObject::info)) {
- if (thisValue->isObject(&RegExpPrototype::info))
+ 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);
+ UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
result.append('/');
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
+ if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
result.append('g');
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
+ if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
result.append('i');
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
+ if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
result.append('m');
return jsNontrivialString(exec, result);
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/ScopeChain.h b/src/3rdparty/webkit/JavaScriptCore/runtime/ScopeChain.h
index 32b5e92..6f1560a 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/ScopeChain.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/ScopeChain.h
@@ -41,6 +41,18 @@ namespace JSC {
{
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;
@@ -171,6 +183,9 @@ namespace JSC {
{
if (m_node)
m_node->deref();
+#ifndef NDEBUG
+ m_node = 0;
+#endif
}
void swap(ScopeChain&);
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.cpp
index 06811b9..87b49f0 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.cpp
@@ -29,48 +29,52 @@
#include "JSGlobalObject.h"
#include "JSString.h"
+#include <wtf/Noncopyable.h>
+
namespace JSC {
+static const unsigned numCharactersToStore = 0x100;
-class SmallStringsStorage {
+class SmallStringsStorage : Noncopyable {
public:
SmallStringsStorage();
- ~SmallStringsStorage();
- UString::Rep* rep(unsigned char character) { return &reps[character]; }
+ UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
private:
- UChar characters[0x100];
- UString::Rep* reps;
+ UChar m_characters[numCharactersToStore];
+ UString::BaseString m_base;
+ UString::Rep m_reps[numCharactersToStore];
};
SmallStringsStorage::SmallStringsStorage()
- : reps(static_cast<UString::Rep*>(fastZeroedMalloc(sizeof(UString::Rep) * 0x100)))
+ : m_base(m_characters, numCharactersToStore)
{
- for (unsigned i = 0; i < 0x100; ++i) {
- characters[i] = i;
- reps[i].offset = i;
- reps[i].len = 1;
- reps[i].rc = 1;
- reps[i].baseString = &reps[0];
- }
- reps[0].rc = 0x101;
- reps[0].buf = characters;
-
+ m_base.rc = numCharactersToStore + 1;
// make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
- reps[0].usedCapacity = 0x101;
- reps[0].capacity = 0x101;
-}
+ m_base.usedCapacity = numCharactersToStore + 1;
+ m_base.capacity = numCharactersToStore + 1;
+ m_base.checkConsistency();
-SmallStringsStorage::~SmallStringsStorage()
-{
- fastFree(reps);
+ 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)
{
- for (unsigned i = 0; i < 0x100; ++i)
+ COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
+
+ for (unsigned i = 0; i < numCharactersToStore; ++i)
m_singleCharacterStrings[i] = 0;
}
@@ -82,12 +86,24 @@ void SmallStrings::mark()
{
if (m_emptyString && !m_emptyString->marked())
m_emptyString->mark();
- for (unsigned i = 0; i < 0x100; ++i) {
+ 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);
@@ -109,4 +125,4 @@ UString::Rep* SmallStrings::singleCharacterStringRep(unsigned char character)
return m_storage->rep(character);
}
-}
+} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.h b/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.h
index 7e5f5c8..e7f1170 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/SmallStrings.h
@@ -55,9 +55,11 @@ namespace JSC {
}
UString::Rep* singleCharacterStringRep(unsigned char character);
-
+
void mark();
-
+
+ unsigned count() const;
+
private:
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
@@ -66,7 +68,7 @@ namespace JSC {
JSString* m_singleCharacterStrings[0x100];
OwnPtr<SmallStringsStorage> m_storage;
};
-
-}
-#endif
+} // namespace JSC
+
+#endif // SmallStrings_h
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringConstructor.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringConstructor.cpp
index bac819f..6380445 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringConstructor.cpp
@@ -21,26 +21,27 @@
#include "config.h"
#include "StringConstructor.h"
+#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "PrototypeFunction.h"
#include "StringPrototype.h"
namespace JSC {
-static NEVER_INLINE JSValuePtr stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
+static NEVER_INLINE JSValue stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
{
UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar)));
UChar* p = buf;
ArgList::const_iterator end = args.end();
for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- *p++ = static_cast<UChar>((*it).jsValue(exec)->toUInt32(exec));
+ *p++ = static_cast<UChar>((*it).toUInt32(exec));
return jsString(exec, UString(buf, p - buf, false));
}
-static JSValuePtr stringFromCharCode(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
if (LIKELY(args.size() == 1))
- return jsSingleCharacterString(exec, args.at(exec, 0)->toUInt32(exec));
+ return jsSingleCharacterString(exec, args.at(0).toUInt32(exec));
return stringFromCharCodeSlowCase(exec, args);
}
@@ -53,7 +54,7 @@ StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<Structure> stru
putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
// ECMA 15.5.3.2 fromCharCode()
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
+ 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);
@@ -64,7 +65,7 @@ static JSObject* constructWithStringConstructor(ExecState* exec, JSObject*, cons
{
if (args.isEmpty())
return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure());
- return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(exec, 0)->toString(exec));
+ return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(0).toString(exec));
}
ConstructType StringConstructor::getConstructData(ConstructData& constructData)
@@ -74,11 +75,11 @@ ConstructType StringConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.5.1
-static JSValuePtr callStringConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callStringConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
if (args.isEmpty())
return jsEmptyString(exec);
- return jsString(exec, args.at(exec, 0)->toString(exec));
+ return jsString(exec, args.at(0).toString(exec));
}
CallType StringConstructor::getCallData(CallData& callData)
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.cpp
index 093f5de..fb44498 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.cpp
@@ -61,7 +61,7 @@ bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pr
return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}
-void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
if (propertyName == exec->propertyNames().length)
return;
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h
index 540c576..ea3a045 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObject.h
@@ -36,16 +36,16 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState* exec, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
virtual const ClassInfo* classInfo() const { return &info; }
- static const ClassInfo info;
+ static const JS_EXPORTDATA ClassInfo info;
JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
- static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType));
}
@@ -59,9 +59,9 @@ namespace JSC {
virtual JSString* toThisJSString(ExecState*);
};
- StringObject* asStringObject(JSValuePtr);
+ StringObject* asStringObject(JSValue);
- inline StringObject* asStringObject(JSValuePtr value)
+ inline StringObject* asStringObject(JSValue value)
{
ASSERT(asObject(value)->inherits(&StringObject::info));
return static_cast<StringObject*>(asObject(value));
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index 72c0f47..bc5c0a5 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -42,7 +42,7 @@ namespace JSC {
{
}
- static PassRefPtr<Structure> createStructure(JSValuePtr proto)
+ static PassRefPtr<Structure> createStructure(JSValue proto)
{
return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined));
}
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
index 1f43cd6..d6939cb 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "StringPrototype.h"
+#include "CachedCall.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "ObjectPrototype.h"
@@ -37,36 +38,36 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(StringPrototype);
-static JSValuePtr stringProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncCharAt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncConcat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncMatch(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncReplace(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSearch(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSlice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSplit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSubstr(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSubstring(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-
-static JSValuePtr stringProtoFuncBig(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSmall(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncBlink(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncBold(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncFixed(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncItalics(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncStrike(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSub(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSup(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncFontcolor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncFontsize(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncAnchor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncLink(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+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&);
}
@@ -140,13 +141,12 @@ static inline UString substituteBackreferences(const UString& replacement, const
if (i + 1 == replacement.size())
break;
- unsigned short ref = replacement[i + 1];
+ UChar ref = replacement[i + 1];
if (ref == '$') {
// "$$" -> "$"
++i;
substitutedReplacement.append(replacement.data() + offset, i - offset);
offset = i + 1;
- substitutedReplacement.append('$');
continue;
}
@@ -205,21 +205,21 @@ 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());
}
-JSValuePtr stringProtoFuncReplace(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- JSString* sourceVal = thisValue->toThisJSString(exec);
+ JSString* sourceVal = thisValue.toThisJSString(exec);
const UString& source = sourceVal->value();
- JSValuePtr pattern = args.at(exec, 0);
+ JSValue pattern = args.at(0);
- JSValuePtr replacement = args.at(exec, 1);
+ JSValue replacement = args.at(1);
UString replacementString;
CallData callData;
- CallType callType = replacement->getCallData(callData);
+ CallType callType = replacement.getCallData(callData);
if (callType == CallTypeNone)
- replacementString = replacement->toString(exec);
+ replacementString = replacement.toString(exec);
- if (pattern->isObject(&RegExpObject::info)) {
+ if (pattern.isObject(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(pattern)->regExp();
bool global = reg->global();
@@ -232,167 +232,223 @@ JSValuePtr stringProtoFuncReplace(ExecState* exec, JSObject*, JSValuePtr thisVal
Vector<UString, 16> replacements;
// This is either a loop (if global is set) or a one-way (if not).
- do {
- int matchIndex;
- int matchLen;
- int* ovector;
- regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
- if (matchIndex < 0)
- break;
-
- sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+ 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));
- if (callType != CallTypeNone) {
int completeMatchStart = ovector[0];
- ArgList args;
-
- for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
+ unsigned i = 0;
+ for (; i < reg->numSubpatterns() + 1; ++i) {
int matchStart = ovector[i * 2];
int matchLen = ovector[i * 2 + 1] - matchStart;
if (matchStart < 0)
- args.append(jsUndefined());
+ cachedCall.setArgument(i, jsUndefined());
else
- args.append(jsSubstring(exec, source, matchStart, matchLen));
+ cachedCall.setArgument(i, 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));
+ 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;
- } else
- replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
- lastIndex = matchIndex + matchLen;
- startPosition = lastIndex;
+ lastIndex = matchIndex + matchLen;
+ startPosition = lastIndex;
- // special case of empty match
- if (matchLen == 0) {
- startPosition++;
- if (startPosition > source.size())
+ // 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;
- }
- } while (global);
- if (lastIndex < source.size())
- sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+ sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
- UString result = source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
+ if (callType != CallTypeNone) {
+ int completeMatchStart = ovector[0];
+ MarkedArgumentBuffer args;
- if (result == source)
+ 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;
- return jsString(exec, result);
+ 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()));
}
- // First arg is a string
- UString patternString = pattern->toString(exec);
+ // Not a regular expression, so treat the pattern as a string.
+
+ UString patternString = pattern.toString(exec);
int matchPos = source.find(patternString);
- int matchLen = patternString.size();
- // Do the replacement
+
if (matchPos == -1)
return sourceVal;
+ int matchLen = patternString.size();
if (callType != CallTypeNone) {
- ArgList args;
+ 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);
+ replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec);
}
int ovector[2] = { matchPos, matchPos + matchLen };
- return jsString(exec, source.substr(0, matchPos)
- + substituteBackreferences(replacementString, source, ovector, 0)
- + source.substr(matchPos + matchLen));
+ return jsString(exec, source.replaceRange(matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0)));
}
-JSValuePtr stringProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
// Also used for valueOf.
- if (thisValue->isString())
+ if (thisValue.isString())
return thisValue;
- if (thisValue->isObject(&StringObject::info))
+ if (thisValue.isObject(&StringObject::info))
return asStringObject(thisValue)->internalValue();
return throwError(exec, TypeError);
}
-JSValuePtr stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
unsigned len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- if (JSImmediate::isNumber(a0)) {
- uint32_t i;
- if (JSImmediate::getUInt32(a0, i) && i < len)
+ 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);
+ double dpos = a0.toInteger(exec);
if (dpos >= 0 && dpos < len)
return jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos));
return jsEmptyString(exec);
}
-JSValuePtr stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
unsigned len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- if (JSImmediate::isNumber(a0)) {
- uint32_t i;
- if (JSImmediate::getUInt32(a0, i) && i < len)
+ 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);
+ double dpos = a0.toInteger(exec);
if (dpos >= 0 && dpos < len)
return jsNumber(exec, s[static_cast<int>(dpos)]);
return jsNaN(exec);
}
-JSValuePtr stringProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
ArgList::const_iterator end = args.end();
for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- s += (*it).jsValue(exec)->toString(exec);
+ s += (*it).toString(exec);
return jsString(exec, s);
}
-JSValuePtr stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- JSValuePtr a1 = args.at(exec, 1);
- UString u2 = a0->toString(exec);
- double dpos = a1->toInteger(exec);
- if (dpos < 0)
- dpos = 0;
- else if (dpos > len)
- dpos = len;
- return jsNumber(exec, s.find(u2, static_cast<int>(dpos)));
+ JSValue 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));
}
-JSValuePtr stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- JSValuePtr a1 = args.at(exec, 1);
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(1);
- UString u2 = a0->toString(exec);
- double dpos = a1->toIntegerPreserveNaN(exec);
+ UString u2 = a0.toString(exec);
+ double dpos = a1.toIntegerPreserveNaN(exec);
if (dpos < 0)
dpos = 0;
else if (!(dpos <= len)) // true for NaN
@@ -400,16 +456,16 @@ JSValuePtr stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thi
return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
}
-JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
+ JSValue a0 = args.at(0);
UString u = s;
RefPtr<RegExp> reg;
RegExpObject* imp = 0;
- if (a0->isObject(&RegExpObject::info))
+ if (a0.isObject(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -417,7 +473,7 @@ JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue
* 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));
+ reg = RegExp::create(&exec->globalData(), a0.toString(exec));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
@@ -431,7 +487,7 @@ JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue
}
// return array of matches
- ArgList list;
+ MarkedArgumentBuffer list;
int lastIndex = 0;
while (pos >= 0) {
list.append(jsSubstring(exec, u, pos, matchLength));
@@ -451,15 +507,15 @@ JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue
return constructArray(exec, list);
}
-JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
+ JSValue a0 = args.at(0);
UString u = s;
RefPtr<RegExp> reg;
- if (a0->isObject(&RegExpObject::info))
+ if (a0.isObject(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -467,7 +523,7 @@ JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValu
* 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));
+ reg = RegExp::create(&exec->globalData(), a0.toString(exec));
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
@@ -476,17 +532,17 @@ JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValu
return jsNumber(exec, pos);
}
-JSValuePtr stringProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- JSValuePtr a1 = args.at(exec, 1);
+ 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 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) {
@@ -500,18 +556,18 @@ JSValuePtr stringProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue
return jsEmptyString(exec);
}
-JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
- JSValuePtr a1 = args.at(exec, 1);
+ 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)) {
+ 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
@@ -538,7 +594,7 @@ JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue
}
}
} else {
- UString u2 = a0->toString(exec);
+ UString u2 = a0.toString(exec);
if (u2.isEmpty()) {
if (s.isEmpty()) {
// empty separator matches empty string -> empty array
@@ -562,16 +618,16 @@ JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue
return result;
}
-JSValuePtr stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- JSValuePtr a1 = args.at(exec, 1);
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(1);
- double start = a0->toInteger(exec);
- double length = a1->isUndefined() ? len : a1->toInteger(exec);
+ double start = a0.toInteger(exec);
+ double length = a1.isUndefined() ? len : a1.toInteger(exec);
if (start >= len || length <= 0)
return jsEmptyString(exec);
if (start < 0) {
@@ -584,16 +640,16 @@ JSValuePtr stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValuePtr thisValu
return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(length));
}
-JSValuePtr stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValuePtr a0 = args.at(exec, 0);
- JSValuePtr a1 = args.at(exec, 1);
+ JSValue a0 = args.at(0);
+ JSValue a1 = args.at(1);
- double start = a0->toNumber(exec);
- double end = a1->toNumber(exec);
+ double start = a0.toNumber(exec);
+ double end = a1.toNumber(exec);
if (isnan(start))
start = 0;
if (isnan(end))
@@ -606,7 +662,7 @@ JSValuePtr stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValuePtr thisV
start = len;
if (end > len)
end = len;
- if (a1->isUndefined())
+ if (a1.isUndefined())
end = len;
if (start > end) {
double temp = end;
@@ -616,9 +672,9 @@ JSValuePtr stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValuePtr thisV
return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(end) - static_cast<unsigned>(start));
}
-JSValuePtr stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- JSString* sVal = thisValue->toThisJSString(exec);
+ JSString* sVal = thisValue.toThisJSString(exec);
const UString& s = sVal->value();
int sSize = s.size();
@@ -650,9 +706,9 @@ JSValuePtr stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValuePtr thi
return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
-JSValuePtr stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- JSString* sVal = thisValue->toThisJSString(exec);
+ JSString* sVal = thisValue.toThisJSString(exec);
const UString& s = sVal->value();
int sSize = s.size();
@@ -684,96 +740,155 @@ JSValuePtr stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValuePtr thi
return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
-JSValuePtr stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+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);
- JSValuePtr a0 = args.at(exec, 0);
- return jsNumber(exec, localeCompare(s, a0->toString(exec)));
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
+ return jsNumber(exec, localeCompare(s, a0.toString(exec)));
}
-JSValuePtr stringProtoFuncBig(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<big>" + s + "</big>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<big>" + s + "</big>");
}
-JSValuePtr stringProtoFuncSmall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<small>" + s + "</small>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<small>" + s + "</small>");
}
-JSValuePtr stringProtoFuncBlink(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<blink>" + s + "</blink>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<blink>" + s + "</blink>");
}
-JSValuePtr stringProtoFuncBold(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<b>" + s + "</b>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<b>" + s + "</b>");
}
-JSValuePtr stringProtoFuncFixed(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
return jsString(exec, "<tt>" + s + "</tt>");
}
-JSValuePtr stringProtoFuncItalics(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<i>" + s + "</i>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<i>" + s + "</i>");
}
-JSValuePtr stringProtoFuncStrike(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<strike>" + s + "</strike>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<strike>" + s + "</strike>");
}
-JSValuePtr stringProtoFuncSub(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<sub>" + s + "</sub>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<sub>" + s + "</sub>");
}
-JSValuePtr stringProtoFuncSup(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<sup>" + s + "</sup>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<sup>" + s + "</sup>");
}
-JSValuePtr stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
- return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
+ return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
}
-JSValuePtr stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
- return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
-}
+ UString s = thisValue.toThisString(exec);
+ JSValue a0 = args.at(0);
-JSValuePtr stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
-{
- UString s = thisValue->toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
- return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
-}
+ 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));
+ }
-JSValuePtr stringProtoFuncLink(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
-{
- UString s = thisValue->toThisString(exec);
- JSValuePtr a0 = args.at(exec, 0);
- return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
+ 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/webkit/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp
index 5fcde7b..3597a5c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.cpp
@@ -65,15 +65,15 @@ static const unsigned newTableSize = 16;
static WTF::RefCountedLeakCounter structureCounter("Structure");
#if ENABLE(JSC_MULTIPLE_THREADS)
-static Mutex ignoreSetMutex;
+static Mutex& ignoreSetMutex = *(new Mutex);
#endif
static bool shouldIgnoreLeaks;
-static HashSet<Structure*> ignoreSet;
+static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>);
#endif
#if DUMP_STRUCTURE_ID_STATISTICS
-static HashSet<Structure*> liveStructureSet;
+static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
#endif
void Structure::dumpStatistics()
@@ -120,12 +120,10 @@ void Structure::dumpStatistics()
#endif
}
-Structure::Structure(JSValuePtr prototype, const TypeInfo& typeInfo)
+Structure::Structure(JSValue prototype, const TypeInfo& typeInfo)
: m_typeInfo(typeInfo)
, m_prototype(prototype)
- , m_cachedPrototypeChain(0)
- , m_previous(0)
- , m_nameInPrevious(0)
+ , m_specificValueInPrevious(0)
, m_propertyTable(0)
, m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
, m_offset(noOffset)
@@ -136,7 +134,7 @@ Structure::Structure(JSValuePtr prototype, const TypeInfo& typeInfo)
, m_attributesInPrevious(0)
{
ASSERT(m_prototype);
- ASSERT(m_prototype->isObject() || m_prototype->isNull());
+ ASSERT(m_prototype.isObject() || m_prototype.isNull());
m_transitions.singleTransition = 0;
@@ -161,8 +159,8 @@ Structure::~Structure()
if (m_previous->m_usingSingleTransitionSlot) {
m_previous->m_transitions.singleTransition = 0;
} else {
- ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m_attributesInPrevious)));
- m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious));
+ 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(m_nameInPrevious.get(), make_pair(m_attributesInPrevious, m_specificValueInPrevious)));
}
}
@@ -178,6 +176,8 @@ Structure::~Structure()
if (UString::Rep* key = m_propertyTable->entries()[i].key)
key->deref();
}
+
+ delete m_propertyTable->deletedOffsets;
fastFree(m_propertyTable);
}
@@ -280,59 +280,34 @@ void Structure::materializePropertyMap()
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, ++m_propertyTable->lastIndexUsed);
+ PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed);
insertIntoPropertyMapHashTable(entry);
}
}
void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
{
- bool shouldCache = propertyNames.cacheable() && !(propertyNames.size() || m_isDictionary);
+ bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary);
- if (shouldCache) {
- if (m_cachedPropertyNameArrayData) {
- if (structureChainsAreEqual(m_cachedPropertyNameArrayData->cachedPrototypeChain(), cachedPrototypeChain())) {
- propertyNames.setData(m_cachedPropertyNameArrayData);
- return;
- }
+ if (shouldCache && m_cachedPropertyNameArrayData) {
+ if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
+ propertyNames.setData(m_cachedPropertyNameArrayData);
+ return;
}
- propertyNames.setCacheable(false);
+ clearEnumerationCache();
}
- getEnumerablePropertyNamesInternal(propertyNames);
+ getEnumerableNamesFromPropertyTable(propertyNames);
+ getEnumerableNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames);
- // Add properties from the static hashtables of properties
- for (const ClassInfo* info = baseObject->classInfo(); info; info = info->parentClass) {
- const HashTable* table = info->propHashTable(exec);
- if (!table)
- continue;
- table->initializeIfNeeded(exec);
- ASSERT(table->table);
-#if ENABLE(PERFECT_HASH_SIZE)
- int hashSizeMask = table->hashSizeMask;
-#else
- int hashSizeMask = table->compactSize - 1;
-#endif
- const HashEntry* entry = table->table;
- for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
- if (entry->key() && !(entry->attributes() & DontEnum))
- propertyNames.add(entry->key());
- }
- }
-
- if (m_prototype->isObject())
+ if (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) {
- if (m_cachedPropertyNameArrayData)
- m_cachedPropertyNameArrayData->setCachedStructure(0);
-
m_cachedPropertyNameArrayData = propertyNames.data();
-
- StructureChain* chain = cachedPrototypeChain();
- if (!chain)
- chain = createCachedPrototypeChain();
- m_cachedPropertyNameArrayData->setCachedPrototypeChain(chain);
+ m_cachedPropertyNameArrayData->setCachedPrototypeChain(prototypeChain(exec));
m_cachedPropertyNameArrayData->setCachedStructure(this);
}
}
@@ -352,20 +327,69 @@ void Structure::growPropertyStorageCapacity()
m_propertyStorageCapacity *= 2;
}
-PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
+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) {
+ 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(propertyName.ustring().rep(), attributes))) {
+ if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), make_pair(attributes, specificValue)))) {
ASSERT(existingTransition->m_offset != noOffset);
offset = existingTransition->m_offset;
return existingTransition;
@@ -375,25 +399,27 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct
return 0;
}
-PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
+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, offset));
+ ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
if (structure->transitionCount() > s_maxTransitionLength) {
RefPtr<Structure> transition = toDictionaryTransition(structure);
- offset = transition->put(propertyName, attributes);
+ 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;
@@ -411,7 +437,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
transition->createPropertyMapHashTable();
}
- offset = transition->put(propertyName, attributes);
+ offset = transition->put(propertyName, attributes, specificValue);
if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
transition->growPropertyStorageCapacity();
@@ -427,9 +453,9 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
structure->m_usingSingleTransitionSlot = false;
StructureTransitionTable* transitionTable = new StructureTransitionTable;
structure->m_transitions.table = transitionTable;
- transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition);
+ transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), make_pair(existingTransition->m_attributesInPrevious, existingTransition->m_specificValueInPrevious)), existingTransition);
}
- structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
+ structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), make_pair(attributes, specificValue)), transition.get());
return transition.release();
}
@@ -444,7 +470,7 @@ PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure,
return transition.release();
}
-PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValuePtr prototype)
+PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValue prototype)
{
RefPtr<Structure> transition = create(prototype, structure->typeInfo());
@@ -460,6 +486,25 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
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());
@@ -507,14 +552,14 @@ PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
return structure;
}
-size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
+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);
+ size_t offset = put(propertyName, attributes, specificValue);
if (propertyStorageSize() > propertyStorageCapacity())
growPropertyStorageCapacity();
clearEnumerationCache();
@@ -534,20 +579,6 @@ size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName
return offset;
}
-StructureChain* Structure::createCachedPrototypeChain()
-{
- ASSERT(typeInfo().type() == ObjectType);
- ASSERT(!m_cachedPrototypeChain);
-
- JSValuePtr prototype = storedPrototype();
- if (JSImmediate::isImmediate(prototype))
- return 0;
-
- RefPtr<StructureChain> chain = StructureChain::create(asObject(prototype)->structure());
- setCachedPrototypeChain(chain.release());
- return cachedPrototypeChain();
-}
-
#if DUMP_PROPERTYMAP_STATS
static int numProbes;
@@ -604,16 +635,12 @@ PropertyMapHashTable* Structure::copyPropertyTable()
return newTable;
}
-size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
+size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue)
{
- ASSERT(!propertyName.isNull());
-
materializePropertyMapIfNecessary();
if (!m_propertyTable)
return notFound;
- UString::Rep* rep = propertyName._ustring.rep();
-
unsigned i = rep->computedHash();
#if DUMP_PROPERTYMAP_STATS
@@ -626,6 +653,7 @@ size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
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;
}
@@ -648,12 +676,64 @@ size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
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;
}
}
}
-size_t Structure::put(const Identifier& propertyName, unsigned attributes)
+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);
@@ -723,6 +803,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes)
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;
@@ -795,6 +876,7 @@ size_t Structure::remove(const Identifier& propertyName)
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)
@@ -922,7 +1004,7 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b)
return 0;
}
-void Structure::getEnumerablePropertyNamesInternal(PropertyNameArray& propertyNames)
+void Structure::getEnumerableNamesFromPropertyTable(PropertyNameArray& propertyNames)
{
materializePropertyMapIfNecessary();
if (!m_propertyTable)
@@ -979,6 +1061,25 @@ void Structure::getEnumerablePropertyNamesInternal(PropertyNameArray& propertyNa
}
}
+void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames)
+{
+ // Add properties from the static hashtables of properties
+ for (; classInfo; classInfo = classInfo->parentClass) {
+ const HashTable* table = classInfo->propHashTable(exec);
+ if (!table)
+ continue;
+ table->initializeIfNeeded(exec);
+ ASSERT(table->table);
+
+ int hashSizeMask = table->compactSize - 1;
+ const HashEntry* entry = table->table;
+ for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
+ if (entry->key() && !(entry->attributes() & DontEnum))
+ propertyNames.add(entry->key());
+ }
+ }
+}
+
#if DO_PROPERTYMAP_CONSTENCY_CHECK
void Structure::checkConsistency()
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h
index c326b3f..866999d 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h
@@ -51,7 +51,7 @@ namespace JSC {
class Structure : public RefCounted<Structure> {
public:
friend class JIT;
- static PassRefPtr<Structure> create(JSValuePtr prototype, const TypeInfo& typeInfo)
+ static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo)
{
return adoptRef(new Structure(prototype, typeInfo));
}
@@ -61,10 +61,11 @@ namespace JSC {
static void dumpStatistics();
- static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);
- static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);
+ 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*, JSValuePtr prototype);
+ 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*);
@@ -73,34 +74,38 @@ namespace JSC {
void mark()
{
- if (!m_prototype->marked())
- m_prototype->mark();
+ if (!m_prototype.marked())
+ m_prototype.mark();
}
// These should be used with caution.
- size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
+ size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t removePropertyWithoutTransition(const Identifier& propertyName);
- void setPrototypeWithoutTransition(JSValuePtr prototype) { m_prototype = prototype; }
+ void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; }
bool isDictionary() const { return m_isDictionary; }
const TypeInfo& typeInfo() const { return m_typeInfo; }
- JSValuePtr storedPrototype() const { return m_prototype; }
- JSValuePtr prototypeForLookup(ExecState*);
+ JSValue storedPrototype() const { return m_prototype; }
+ JSValue prototypeForLookup(ExecState*) const;
+ StructureChain* prototypeChain(ExecState*) const;
Structure* previousID() const { return m_previous.get(); }
- StructureChain* createCachedPrototypeChain();
- void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
- StructureChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.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 Identifier& propertyName, unsigned& attributes);
+ 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 getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
@@ -108,12 +113,16 @@ namespace JSC {
bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
+ JSCell* specificValue() { return m_specificValueInPrevious; }
+ void despecifyDictionaryFunction(const Identifier& propertyName);
+
private:
- Structure(JSValuePtr prototype, const TypeInfo&);
+ Structure(JSValue prototype, const TypeInfo&);
- size_t put(const Identifier& propertyName, unsigned attributes);
+ size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t remove(const Identifier& propertyName);
- void getEnumerablePropertyNamesInternal(PropertyNameArray&);
+ void getEnumerableNamesFromPropertyTable(PropertyNameArray&);
+ void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&);
void expandPropertyMapHashTable();
void rehashPropertyMapHashTable();
@@ -123,6 +132,8 @@ namespace JSC {
void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
void checkConsistency();
+ bool despecifyFunction(const Identifier&);
+
PropertyMapHashTable* copyPropertyTable();
void materializePropertyMap();
void materializePropertyMapIfNecessary()
@@ -134,16 +145,13 @@ namespace JSC {
void clearEnumerationCache();
- void* addressOfCount()
- {
- return &m_refCount;
- }
-
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;
@@ -153,8 +161,8 @@ namespace JSC {
TypeInfo m_typeInfo;
- JSValuePtr m_prototype;
- RefPtr<StructureChain> m_cachedPrototypeChain;
+ JSValue m_prototype;
+ mutable RefPtr<StructureChain> m_cachedPrototypeChain;
RefPtr<Structure> m_previous;
RefPtr<UString::Rep> m_nameInPrevious;
@@ -163,6 +171,7 @@ namespace JSC {
Structure* singleTransition;
StructureTransitionTable* table;
} m_transitions;
+ JSCell* m_specificValueInPrevious;
RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
@@ -175,7 +184,7 @@ namespace JSC {
bool m_isPinnedPropertyTable : 1;
bool m_hasGetterSetterProperties : 1;
bool m_usingSingleTransitionSlot : 1;
- unsigned m_attributesInPrevious : 5;
+ unsigned m_attributesInPrevious : 7;
};
inline size_t Structure::get(const Identifier& propertyName)
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp
index 84c67c3..085876c 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.cpp
@@ -32,42 +32,18 @@
namespace JSC {
-StructureChain::StructureChain(Structure* structure)
+StructureChain::StructureChain(Structure* head)
{
- size_t size = 1;
-
- Structure* tmp = structure;
- while (!tmp->storedPrototype()->isNull()) {
+ size_t size = 0;
+ for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
++size;
- tmp = asCell(tmp->storedPrototype())->structure();
- }
m_vector.set(new RefPtr<Structure>[size + 1]);
- size_t i;
- for (i = 0; i < size - 1; ++i) {
- m_vector[i] = structure;
- structure = asObject(structure->storedPrototype())->structure();
- }
- m_vector[i] = structure;
- m_vector[i + 1] = 0;
-}
-
-bool structureChainsAreEqual(StructureChain* chainA, StructureChain* chainB)
-{
- if (!chainA || !chainB)
- return false;
-
- RefPtr<Structure>* a = chainA->head();
- RefPtr<Structure>* b = chainB->head();
- while (1) {
- if (*a != *b)
- return false;
- if (!*a)
- return true;
- a++;
- b++;
- }
+ 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;
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h
index a3a1be2..795e649 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureChain.h
@@ -37,18 +37,15 @@ namespace JSC {
class StructureChain : public RefCounted<StructureChain> {
public:
- static PassRefPtr<StructureChain> create(Structure* structure) { return adoptRef(new StructureChain(structure)); }
-
+ static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
RefPtr<Structure>* head() { return m_vector.get(); }
private:
- StructureChain(Structure* structure);
+ StructureChain(Structure* head);
OwnArrayPtr<RefPtr<Structure> > m_vector;
};
- bool structureChainsAreEqual(StructureChain*, StructureChain*);
-
} // namespace JSC
#endif // StructureChain_h
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h
index 1543049..804cbeb 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -37,7 +37,7 @@ namespace JSC {
class Structure;
struct StructureTransitionTableHash {
- typedef std::pair<RefPtr<UString::Rep>, unsigned> Key;
+ typedef std::pair<RefPtr<UString::Rep>, std::pair<unsigned, JSCell*> > Key;
static unsigned hash(const Key& p)
{
return p.first->computedHash();
@@ -53,13 +53,14 @@ namespace JSC {
struct StructureTransitionTableHashTraits {
typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
- typedef WTF::GenericHashTraits<unsigned> SecondTraits;
- typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
+ 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 && SecondTraits::emptyValueIsZero;
- static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
+ 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 || SecondTraits::needsDestruction;
+ 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); }
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.cpp
new file mode 100644
index 0000000..30ba6e9
--- /dev/null
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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;
+
+// Number of milliseconds between each timeout check.
+static const int intervalBetweenChecks = 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)
+{
+ reset();
+}
+
+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>(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/webkit/JavaScriptCore/runtime/TimeoutChecker.h b/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.h
new file mode 100644
index 0000000..7bfa6d0
--- /dev/null
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/TimeoutChecker.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.
+ * 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();
+
+ void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; }
+
+ unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; }
+
+ void start()
+ {
+ if (!m_startCount)
+ reset();
+ ++m_startCount;
+ }
+
+ void stop()
+ {
+ ASSERT(m_startCount);
+ --m_startCount;
+ }
+
+ void reset();
+
+ bool didTimeOut(ExecState*);
+
+ private:
+ unsigned m_timeoutInterval;
+ unsigned m_timeAtLastCheck;
+ unsigned m_timeExecuting;
+ unsigned m_startCount;
+ unsigned m_ticksUntilNextCheck;
+ };
+
+} // namespace JSC
+
+#endif // TimeoutChecker_h
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/TypeInfo.h b/src/3rdparty/webkit/JavaScriptCore/runtime/TypeInfo.h
index 52da347..70aeed3 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/TypeInfo.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/TypeInfo.h
@@ -35,13 +35,22 @@ namespace JSC {
static const unsigned MasqueradesAsUndefined = 1;
static const unsigned ImplementsHasInstance = 1 << 1;
static const unsigned OverridesHasInstance = 1 << 2;
- static const unsigned NeedsThisConversion = 1 << 3;
- static const unsigned HasStandardGetOwnPropertySlot = 1 << 4;
+ 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), m_flags(flags) { }
+ 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; }
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp
index 45df248..0eb46da 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.cpp
@@ -1,7 +1,8 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * 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
@@ -61,6 +62,9 @@ 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 = 30;
+
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); }
@@ -92,7 +96,7 @@ static inline void copyChars(UChar* destination, const UChar* source, unsigned n
memcpy(destination, source, numCharacters * sizeof(UChar));
}
-COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes)
+COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes);
CString::CString(const char* c)
: m_length(strlen(c))
@@ -186,86 +190,59 @@ bool operator==(const CString& c1, const CString& c2)
// 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::Rep UString::Rep::null = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::null, 0, 0, 0, 0, 0, 0 };
-UString::Rep UString::Rep::empty = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::empty, 0, &sharedEmptyChar, 0, 0, 0, 0 };
-
-static char* statBuffer = 0; // Only used for debugging via UString::ascii().
+UString::BaseString* UString::Rep::nullBaseString;
+UString::BaseString* UString::Rep::emptyBaseString;
+UString* UString::nullUString;
-PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l)
+static void initializeStaticBaseString(UString::BaseString& base)
{
- UChar* copyD = static_cast<UChar*>(fastMalloc(l * sizeof(UChar)));
- copyChars(copyD, d, l);
- return create(copyD, l);
+ base.rc = INT_MAX / 2;
+ base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
+ base.checkConsistency();
}
-PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
+void initializeUString()
{
- Rep* r = new Rep;
- r->offset = 0;
- r->len = l;
- r->rc = 1;
- r->_hash = 0;
- r->m_identifierTable = 0;
- r->baseString = r;
- r->reportedCost = 0;
- r->buf = d;
- r->usedCapacity = l;
- r->capacity = l;
- r->usedPreCapacity = 0;
- r->preCapacity = 0;
+ UString::Rep::nullBaseString = new UString::BaseString(0, 0);
+ initializeStaticBaseString(*UString::Rep::nullBaseString);
- r->checkConsistency();
+ UString::Rep::emptyBaseString = new UString::BaseString(&sharedEmptyChar, 0);
+ initializeStaticBaseString(*UString::Rep::emptyBaseString);
- // steal the single reference this Rep was created with
- return adoptRef(r);
+ UString::nullUString = new UString;
}
-PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
-{
- ASSERT(base);
- base->checkConsistency();
-
- int baseOffset = base->offset;
-
- base = base->baseString;
-
- ASSERT(-(offset + baseOffset) <= base->usedPreCapacity);
- ASSERT(offset + baseOffset + length <= base->usedCapacity);
-
- Rep* r = new Rep;
- r->offset = baseOffset + offset;
- r->len = length;
- r->rc = 1;
- r->_hash = 0;
- r->m_identifierTable = 0;
- r->baseString = base.releaseRef();
- r->reportedCost = 0;
- r->buf = 0;
- r->usedCapacity = 0;
- r->capacity = 0;
- r->usedPreCapacity = 0;
- r->preCapacity = 0;
-
- r->checkConsistency();
+static char* statBuffer = 0; // Only used for debugging via UString::ascii().
- // steal the single reference this Rep was created with
- return adoptRef(r);
+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;
+ 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::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;
+}
+
void UString::Rep::destroy()
{
checkConsistency();
@@ -275,10 +252,15 @@ void UString::Rep::destroy()
if (!isStatic()) {
if (identifierTable())
Identifier::remove(this);
- if (baseString == this)
- fastFree(buf);
- else
- baseString->deref();
+
+ UString::BaseString* base = baseString();
+ if (base == this) {
+ if (m_sharedBuffer)
+ m_sharedBuffer->deref();
+ else
+ fastFree(base->buf);
+ } else
+ base->deref();
delete this;
}
@@ -380,17 +362,10 @@ unsigned UString::Rep::computeHash(const char* s, int l)
#ifndef NDEBUG
void UString::Rep::checkConsistency() const
{
- // Only base strings have non-zero shared data.
- if (this != baseString) {
- ASSERT(!buf);
- ASSERT(!usedCapacity);
- ASSERT(!capacity);
- ASSERT(!usedPreCapacity);
- ASSERT(!preCapacity);
- }
+ const UString::BaseString* base = baseString();
// There is no recursion for base strings.
- ASSERT(baseString == baseString->baseString);
+ ASSERT(base == base->baseString());
if (isStatic()) {
// There are only two static strings: null and empty.
@@ -401,63 +376,148 @@ void UString::Rep::checkConsistency() const
}
// The string fits in buffer.
- ASSERT(baseString->usedPreCapacity <= baseString->preCapacity);
- ASSERT(baseString->usedCapacity <= baseString->capacity);
- ASSERT(-offset <= baseString->usedPreCapacity);
- ASSERT(offset + len <= baseString->usedCapacity);
+ ASSERT(base->usedPreCapacity <= base->preCapacity);
+ ASSERT(base->usedCapacity <= base->capacity);
+ ASSERT(-offset <= base->usedPreCapacity);
+ ASSERT(offset + len <= base->usedCapacity);
}
#endif
-// put these early so they can be inlined
-static inline size_t expandedSize(size_t size, size_t otherSize)
+UString::SharedUChar* UString::BaseString::sharedBuffer()
{
- // Do the size calculation in two parts, returning overflowIndicator if
- // we overflow the maximum value that we can handle.
- if (size > maxUChars())
- return overflowIndicator();
-
- size_t expandedSize = ((size + 10) / 10 * 11) + 1;
- if (maxUChars() - expandedSize < otherSize)
- return overflowIndicator();
+ if (len < minLengthToShare)
+ return 0;
- return expandedSize + otherSize;
+ if (!m_sharedBuffer)
+ setSharedBuffer(SharedUChar::create(new OwnFastMallocPtr<UChar>(buf)));
+ return m_sharedBuffer;
}
-inline int UString::usedCapacity() const
+void UString::BaseString::setSharedBuffer(PassRefPtr<UString::SharedUChar> sharedBuffer)
{
- return m_rep->baseString->usedCapacity;
+ // 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();
}
-inline int UString::usedPreCapacity() const
+bool UString::BaseString::slowIsBufferReadOnly()
{
- return m_rep->baseString->usedPreCapacity;
+ // 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::Rep* r = rep->baseString;
+ UString::BaseString* base = rep->baseString();
- if (requiredLength > r->capacity) {
- size_t newCapacity = expandedSize(requiredLength, r->preCapacity);
- UChar* oldBuf = r->buf;
- r->buf = reallocChars(r->buf, newCapacity);
- if (!r->buf) {
- r->buf = oldBuf;
+ 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;
}
- r->capacity = newCapacity - r->preCapacity;
+ base->capacity = newCapacity - base->preCapacity;
}
- if (requiredLength > r->usedCapacity)
- r->usedCapacity = requiredLength;
+ 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))
@@ -467,42 +527,43 @@ void UString::expandCapacity(int requiredLength)
void UString::expandPreCapacity(int requiredPreCap)
{
m_rep->checkConsistency();
+ ASSERT(!m_rep->baseString()->isBufferReadOnly());
- Rep* r = m_rep->baseString;
+ BaseString* base = m_rep->baseString();
- if (requiredPreCap > r->preCapacity) {
- size_t newCapacity = expandedSize(requiredPreCap, r->capacity);
- int delta = newCapacity - r->capacity - r->preCapacity;
+ 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, r->buf, r->capacity + r->preCapacity);
- fastFree(r->buf);
- r->buf = newBuf;
+ copyChars(newBuf + delta, base->buf, base->capacity + base->preCapacity);
+ fastFree(base->buf);
+ base->buf = newBuf;
- r->preCapacity = newCapacity - r->capacity;
+ base->preCapacity = newCapacity - base->capacity;
}
- if (requiredPreCap > r->usedPreCapacity)
- r->usedPreCapacity = requiredPreCap;
+ if (requiredPreCap > base->usedPreCapacity)
+ base->usedPreCapacity = requiredPreCap;
m_rep->checkConsistency();
}
-PassRefPtr<UString::Rep> createRep(const char* c)
+static PassRefPtr<UString::Rep> createRep(const char* c)
{
if (!c)
- return &UString::Rep::null;
+ return &UString::Rep::null();
if (!c[0])
- return &UString::Rep::empty;
+ return &UString::Rep::empty();
size_t length = strlen(c);
UChar* d = allocChars(length);
if (!d)
- return &UString::Rep::null;
+ 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
@@ -519,7 +580,7 @@ UString::UString(const char* c)
UString::UString(const UChar* c, int length)
{
if (length == 0)
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
else
m_rep = Rep::createCopying(c, length);
}
@@ -527,7 +588,7 @@ UString::UString(const UChar* c, int length)
UString::UString(UChar* c, int length, bool copy)
{
if (length == 0)
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
else if (copy)
m_rep = Rep::createCopying(c, length);
else
@@ -537,11 +598,22 @@ UString::UString(UChar* c, int length, bool copy)
UString::UString(const Vector<UChar>& buffer)
{
if (!buffer.size())
- m_rep = &Rep::empty;
+ 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;
@@ -551,6 +623,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
int thisSize = rep->size();
int thisOffset = rep->offset;
int length = thisSize + tSize;
+ UString::BaseString* base = rep->baseString();
// possible cases:
if (tSize == 0) {
@@ -558,34 +631,34 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
} else if (thisSize == 0) {
// this is empty
rep = UString::Rep::createCopying(tData, tSize);
- } else if (rep->baseIsSelf() && rep->rc == 1) {
+ } 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(), thisOffset + length))
- rep = &UString::Rep::null;
+ 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 == rep->baseString->usedCapacity && thisSize >= minShareSize) {
+ } 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(), thisOffset + length))
- rep = &UString::Rep::null;
+ 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 with someone using more capacity, gotta make a whole new string
+ // 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;
+ rep = &UString::Rep::null();
else {
copyChars(d, rep->data(), thisSize);
copyChars(d + thisSize, tData, tSize);
rep = UString::Rep::create(d, length);
- rep->capacity = newCapacity;
+ rep->baseString()->capacity = newCapacity;
}
}
@@ -604,6 +677,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
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) {
@@ -611,9 +685,9 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep = createRep(t);
} else if (tSize == 0) {
// t is empty, we'll just return *this below.
- } else if (rep->baseIsSelf() && rep->rc == 1) {
+ } else if (rep == base && !base->isShared()) {
// this is direct and has refcount of 1 (so we can just alter it directly)
- expandCapacity(rep.get(), thisOffset + length);
+ expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
UChar* d = rep->data();
if (d) {
for (int i = 0; i < tSize; ++i)
@@ -621,9 +695,9 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep->len = length;
rep->_hash = 0;
}
- } else if (thisOffset + thisSize == rep->baseString->usedCapacity && thisSize >= minShareSize) {
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
// this string reaches the end of the buffer - extend it
- expandCapacity(rep.get(), thisOffset + length);
+ expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
UChar* d = rep->data();
if (d) {
for (int i = 0; i < tSize; ++i)
@@ -631,17 +705,17 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep = UString::Rep::create(rep, 0, length);
}
} else {
- // this is shared with someone using more capacity, gotta make a whole new string
+ // 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;
+ 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->capacity = newCapacity;
+ rep->baseString()->capacity = newCapacity;
}
}
@@ -656,13 +730,19 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
b->checkConsistency();
int aSize = a->size();
- int aOffset = a->offset;
int bSize = b->size();
- int bOffset = b->offset;
- int length = aSize + bSize;
+ 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;
@@ -670,21 +750,19 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
if (bSize == 0)
return a;
- if (bSize == 1 && aOffset + aSize == a->baseString->usedCapacity && aOffset + length <= a->baseString->capacity) {
- // b is a single character (common fast case)
- a->baseString->usedCapacity = aOffset + length;
- a->data()[aSize] = b->data()[0];
- return UString::Rep::create(a, 0, length);
- }
+ int bOffset = b->offset;
+ int length = aSize + bSize;
- if (aOffset + aSize == a->baseString->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize &&
- (-bOffset != b->baseString->usedPreCapacity || 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(aOffset + length);
+ x.expandCapacity(newCapacityWithOverflowCheck(aOffset, length));
if (!a->data() || !x.data())
return 0;
copyChars(a->data() + aSize, b->data(), bSize);
@@ -697,7 +775,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
return result;
}
- if (-bOffset == b->baseString->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
+ 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
@@ -723,7 +801,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
copyChars(d, a->data(), aSize);
copyChars(d + aSize, b->data(), bSize);
PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);
- result->capacity = newCapacity;
+ result->baseString()->capacity = newCapacity;
a->checkConsistency();
b->checkConsistency();
@@ -775,7 +853,8 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
int decimalPoint;
int sign;
- char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
+ char result[80];
+ WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
int length = static_cast<int>(strlen(result));
int i = 0;
@@ -826,15 +905,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
buf[i++] = '\0';
}
- WTF::freedtoa(result);
-
- return concatenate(rep, buf);
-}
-
-const UString& UString::null()
-{
- static UString* n = new UString; // Should be called from main thread at least once to be safely initialized.
- return *n;
+ return concatenate(rep, buf);
}
UString UString::from(int i)
@@ -922,8 +993,9 @@ UString UString::from(double d)
char buf[80];
int decimalPoint;
int sign;
-
- char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
+
+ char result[80];
+ WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
int length = static_cast<int>(strlen(result));
int i = 0;
@@ -974,9 +1046,7 @@ UString UString::from(double d)
buf[i++] = '\0';
}
- WTF::freedtoa(result);
-
- return UString(buf);
+ return UString(buf);
}
UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
@@ -1021,6 +1091,28 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in
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();
@@ -1030,6 +1122,7 @@ UString& UString::append(const UString &t)
int thisOffset = m_rep->offset;
int tSize = t.size();
int length = thisSize + tSize;
+ BaseString* base = m_rep->baseString();
// possible cases:
if (thisSize == 0) {
@@ -1037,23 +1130,23 @@ UString& UString::append(const UString &t)
*this = t;
} else if (tSize == 0) {
// t is empty
- } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
+ } else if (m_rep == base && !base->isShared()) {
// this is direct and has refcount of 1 (so we can just alter it directly)
- expandCapacity(thisOffset + length);
+ 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 == usedCapacity() && thisSize >= minShareSize) {
+ } 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(thisOffset + length);
+ 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 with someone using more capacity, gotta make a whole new string
+ // 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)
@@ -1062,7 +1155,7 @@ UString& UString::append(const UString &t)
copyChars(d, data(), thisSize);
copyChars(d + thisSize, t.data(), tSize);
m_rep = Rep::create(d, length);
- m_rep->capacity = newCapacity;
+ m_rep->baseString()->capacity = newCapacity;
}
}
@@ -1078,6 +1171,18 @@ UString& UString::append(const UChar* tData, int 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);
@@ -1090,6 +1195,7 @@ UString& UString::append(UChar c)
int thisOffset = m_rep->offset;
int length = size();
+ BaseString* base = m_rep->baseString();
// possible cases:
if (length == 0) {
@@ -1101,27 +1207,27 @@ UString& UString::append(UChar c)
else {
d[0] = c;
m_rep = Rep::create(d, 1);
- m_rep->capacity = newCapacity;
+ m_rep->baseString()->capacity = newCapacity;
}
- } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
+ } else if (m_rep == base && !base->isShared()) {
// this is direct and has refcount of 1 (so we can just alter it directly)
- expandCapacity(thisOffset + length + 1);
+ 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 == usedCapacity() && length >= minShareSize) {
+ } else if (thisOffset + length == base->usedCapacity && length >= minShareSize && !base->isBufferReadOnly()) {
// this reaches the end of the string - extend it and share
- expandCapacity(thisOffset + length + 1);
+ 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 with someone using more capacity, gotta make a whole new string
+ // 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)
@@ -1130,7 +1236,7 @@ UString& UString::append(UChar c)
copyChars(d, data(), length);
d[length] = c;
m_rep = Rep::create(d, length + 1);
- m_rep->capacity = newCapacity;
+ m_rep->baseString()->capacity = newCapacity;
}
}
@@ -1185,19 +1291,20 @@ char* UString::ascii() const
UString& UString::operator=(const char* c)
{
if (!c) {
- m_rep = &Rep::null;
+ m_rep = &Rep::null();
return *this;
}
if (!c[0]) {
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
return *this;
}
int l = static_cast<int>(strlen(c));
UChar* d;
- if (m_rep->rc == 1 && l <= m_rep->capacity && m_rep->baseIsSelf() && m_rep->offset == 0 && m_rep->preCapacity == 0) {
- d = m_rep->buf;
+ 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 {
@@ -1413,12 +1520,24 @@ uint32_t UString::toStrictUInt32(bool* ok) const
int UString::find(const UString& f, int pos) const
{
- int sz = size();
int fsz = f.size();
- if (sz < fsz)
- return -1;
+
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;
@@ -1502,19 +1621,6 @@ UString UString::substr(int pos, int len) const
return UString(Rep::create(m_rep, pos, len));
}
-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];
- default:
- return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;
- }
-}
-
bool operator==(const UString& s1, const char *s2)
{
if (s2 == 0)
@@ -1626,13 +1732,13 @@ CString UString::UTF8String(bool strict) const
// 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;
+ 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;
+ return &Rep::null();
}
} // namespace JSC
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h
index 75403c0..6852d91 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/UString.h
@@ -1,6 +1,7 @@
/*
* 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
@@ -26,8 +27,10 @@
#include <stdint.h>
#include <string.h>
#include <wtf/Assertions.h>
-#include <wtf/FastMalloc.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>
@@ -74,10 +77,26 @@ namespace JSC {
friend class JIT;
public:
- struct Rep {
+ typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
+ struct BaseString;
+ struct Rep : Noncopyable {
friend class JIT;
- static PassRefPtr<Rep> create(UChar*, int);
+ 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);
@@ -85,10 +104,13 @@ namespace JSC {
// 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>);
+
void destroy();
- bool baseIsSelf() const { return baseString == this; }
- UChar* data() const { return baseString->buf + baseString->preCapacity + offset; }
+ 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; }
@@ -98,35 +120,115 @@ namespace JSC {
static unsigned computeHash(const char*, int length);
static unsigned computeHash(const char* s) { return computeHash(s, strlen(s)); }
- IdentifierTable* identifierTable() const { return reinterpret_cast<IdentifierTable*>(m_identifierTable & ~static_cast<uintptr_t>(1)); }
- void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTable = reinterpret_cast<intptr_t>(table); }
+ IdentifierTable* identifierTable() const { return m_identifierTableAndFlags.get(); }
+ void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTableAndFlags.set(table); }
- bool isStatic() const { return m_identifierTable & 1; }
- void setStatic(bool v) { ASSERT(!identifierTable()); m_identifierTable = v; }
+ 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;
- intptr_t m_identifierTable; // A pointer to identifier table. The lowest bit is used to indicate whether the string is static (null or empty).
- UString::Rep* baseString;
- size_t reportedCost;
+ PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
+
+ static BaseString& null() { return *nullBaseString; }
+ static BaseString& empty() { return *emptyBaseString; }
- // potentially shared data. 0 if backed up by a base string.
+ 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>);
+ SharedUChar* sharedBuffer();
+
+ bool isBufferReadOnly()
+ {
+ if (!m_sharedBuffer)
+ return false;
+ return slowIsBufferReadOnly();
+ }
+
+ // potentially shared data.
UChar* buf;
- int usedCapacity;
- int capacity;
- int usedPreCapacity;
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();
+ }
+
+ bool slowIsBufferReadOnly();
- static Rep null;
- static Rep empty;
+ friend struct Rep;
+ friend class SmallStringsStorage;
+ friend void initializeUString();
};
public:
@@ -175,11 +277,15 @@ namespace JSC {
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;
@@ -204,7 +310,7 @@ namespace JSC {
const UChar* data() const { return m_rep->data(); }
- bool isNull() const { return (m_rep == &Rep::null); }
+ bool isNull() const { return (m_rep == &Rep::null()); }
bool isEmpty() const { return (!m_rep->len); }
bool is8Bit() const;
@@ -230,7 +336,7 @@ namespace JSC {
UString substr(int pos = 0, int len = -1) const;
- static const UString& null();
+ static const UString& null() { return *nullUString; }
Rep* rep() const { return m_rep.get(); }
static Rep* nullRep();
@@ -243,15 +349,26 @@ namespace JSC {
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);
+ }
+
private:
- int usedCapacity() const;
- int usedPreCapacity() const;
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
};
@@ -259,7 +376,26 @@ namespace JSC {
PassRefPtr<UString::Rep> concatenate(UString::Rep*, int);
PassRefPtr<UString::Rep> concatenate(UString::Rep*, double);
- bool operator==(const UString&, const UString&);
+ 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)
{
@@ -298,6 +434,54 @@ namespace JSC {
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
{
@@ -305,7 +489,7 @@ namespace JSC {
#endif
inline UString::UString()
- : m_rep(&Rep::null)
+ : m_rep(&Rep::null())
{
}
@@ -328,8 +512,9 @@ namespace JSC {
inline size_t UString::cost() const
{
- size_t capacity = (m_rep->baseString->capacity + m_rep->baseString->preCapacity) * sizeof(UChar);
- size_t reportedCost = m_rep->baseString->reportedCost;
+ 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;
@@ -337,7 +522,7 @@ namespace JSC {
if (capacityDelta < static_cast<size_t>(minShareSize))
return 0;
- m_rep->baseString->reportedCost = capacity;
+ base->reportedCost = capacity;
return capacityDelta;
}
@@ -347,6 +532,7 @@ namespace JSC {
static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); }
};
+ void initializeUString();
} // namespace JSC
namespace WTF {