diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /JavaScriptCore/runtime | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_webkit-cad810f21b803229eb11403f9209855525a25d57.zip external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2 |
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'JavaScriptCore/runtime')
205 files changed, 0 insertions, 34911 deletions
diff --git a/JavaScriptCore/runtime/ArgList.cpp b/JavaScriptCore/runtime/ArgList.cpp deleted file mode 100644 index ab2b5d7..0000000 --- a/JavaScriptCore/runtime/ArgList.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "ArgList.h" - -#include "JSValue.h" -#include "JSCell.h" - -using std::min; - -namespace JSC { - -void ArgList::getSlice(int startIndex, ArgList& result) const -{ - if (startIndex <= 0 || static_cast<unsigned>(startIndex) >= m_argCount) { - result = ArgList(m_args, 0); - return; - } - result = ArgList(m_args + startIndex, m_argCount - startIndex); -} - -void MarkedArgumentBuffer::markLists(MarkStack& markStack, ListSet& markSet) -{ - ListSet::iterator end = markSet.end(); - for (ListSet::iterator it = markSet.begin(); it != end; ++it) { - MarkedArgumentBuffer* list = *it; - markStack.appendValues(reinterpret_cast<JSValue*>(list->m_buffer), list->m_size); - } -} - -void MarkedArgumentBuffer::slowAppend(JSValue v) -{ - // As long as our size stays within our Vector's inline - // capacity, all our values are allocated on the stack, and - // therefore don't need explicit marking. Once our size exceeds - // our Vector's inline capacity, though, our values move to the - // heap, where they do need explicit marking. - if (!m_markSet) { - // We can only register for explicit marking once we know which heap - // is the current one, i.e., when a non-immediate value is appended. - if (Heap* heap = Heap::heap(v)) { - ListSet& markSet = heap->markListSet(); - markSet.add(this); - m_markSet = &markSet; - } - } - - if (m_vector.size() < m_vector.capacity()) { - m_vector.uncheckedAppend(v); - return; - } - - // 4x growth would be excessive for a normal vector, but it's OK for Lists - // because they're short-lived. - m_vector.reserveCapacity(m_vector.capacity() * 4); - - m_vector.uncheckedAppend(v); - m_buffer = m_vector.data(); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ArgList.h b/JavaScriptCore/runtime/ArgList.h deleted file mode 100644 index cd563a2..0000000 --- a/JavaScriptCore/runtime/ArgList.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ArgList_h -#define ArgList_h - -#include "CallFrame.h" -#include "Register.h" -#include <wtf/HashSet.h> -#include <wtf/Noncopyable.h> -#include <wtf/Vector.h> - -namespace JSC { - - class MarkStack; - - class MarkedArgumentBuffer : public Noncopyable { - private: - static const unsigned inlineCapacity = 8; - typedef Vector<Register, inlineCapacity> VectorType; - typedef HashSet<MarkedArgumentBuffer*> ListSet; - - public: - typedef VectorType::iterator iterator; - typedef VectorType::const_iterator const_iterator; - - // Constructor for a read-write list, to which you may append values. - // FIXME: Remove all clients of this API, then remove this API. - MarkedArgumentBuffer() - : m_isUsingInlineBuffer(true) - , m_markSet(0) -#ifndef NDEBUG - , m_isReadOnly(false) -#endif - { - m_buffer = m_vector.data(); - m_size = 0; - } - - // Constructor for a read-only list whose data has already been allocated elsewhere. - MarkedArgumentBuffer(Register* buffer, size_t size) - : m_buffer(buffer) - , m_size(size) - , m_isUsingInlineBuffer(true) - , m_markSet(0) -#ifndef NDEBUG - , m_isReadOnly(true) -#endif - { - } - - void initialize(Register* buffer, size_t size) - { - ASSERT(!m_markSet); - ASSERT(isEmpty()); - - m_buffer = buffer; - m_size = size; -#ifndef NDEBUG - m_isReadOnly = true; -#endif - } - - ~MarkedArgumentBuffer() - { - if (m_markSet) - m_markSet->remove(this); - } - - size_t size() const { return m_size; } - bool isEmpty() const { return !m_size; } - - JSValue at(size_t i) const - { - if (i < m_size) - return m_buffer[i].jsValue(); - return jsUndefined(); - } - - void clear() - { - m_vector.clear(); - m_buffer = 0; - m_size = 0; - } - - void append(JSValue v) - { - ASSERT(!m_isReadOnly); - -#if ENABLE(JSC_ZOMBIES) - ASSERT(!v.isZombie()); -#endif - - if (m_isUsingInlineBuffer && m_size < inlineCapacity) { - m_vector.uncheckedAppend(v); - ++m_size; - } else { - // Putting this case all in one function measurably improves - // the performance of the fast "just append to inline buffer" case. - slowAppend(v); - ++m_size; - m_isUsingInlineBuffer = false; - } - } - - void removeLast() - { - ASSERT(m_size); - m_size--; - m_vector.removeLast(); - } - - JSValue last() - { - ASSERT(m_size); - return m_buffer[m_size - 1].jsValue(); - } - - iterator begin() { return m_buffer; } - iterator end() { return m_buffer + m_size; } - - const_iterator begin() const { return m_buffer; } - const_iterator end() const { return m_buffer + m_size; } - - static void markLists(MarkStack&, ListSet&); - - private: - void slowAppend(JSValue); - - Register* m_buffer; - size_t m_size; - bool m_isUsingInlineBuffer; - - VectorType m_vector; - ListSet* m_markSet; -#ifndef NDEBUG - bool m_isReadOnly; -#endif - - private: - // Prohibits new / delete, which would break GC. - friend class JSGlobalData; - - void* operator new(size_t size) - { - return fastMalloc(size); - } - void operator delete(void* p) - { - fastFree(p); - } - - void* operator new[](size_t); - void operator delete[](void*); - - void* operator new(size_t, void*); - void operator delete(void*, size_t); - }; - - class ArgList { - friend class JIT; - public: - typedef JSValue* iterator; - typedef const JSValue* const_iterator; - - ArgList() - : m_args(0) - , m_argCount(0) - { - } - - ArgList(ExecState* exec) - : m_args(reinterpret_cast<JSValue*>(&exec[exec->hostThisRegister() + 1])) - , m_argCount(exec->argumentCount()) - { - } - - ArgList(JSValue* args, unsigned argCount) - : m_args(args) - , m_argCount(argCount) - { -#if ENABLE(JSC_ZOMBIES) - for (size_t i = 0; i < argCount; i++) - ASSERT(!m_args[i].isZombie()); -#endif - } - - 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/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp deleted file mode 100644 index 39886a8..0000000 --- a/JavaScriptCore/runtime/Arguments.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "Arguments.h" - -#include "JSActivation.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" - -using namespace std; - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(Arguments); - -const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 }; - -Arguments::~Arguments() -{ - if (d->extraArguments != d->extraArgumentsFixedBuffer) - delete [] d->extraArguments; -} - -void Arguments::markChildren(MarkStack& markStack) -{ - JSObject::markChildren(markStack); - - if (d->registerArray) - markStack.appendValues(reinterpret_cast<JSValue*>(d->registerArray.get()), d->numParameters); - - if (d->extraArguments) { - unsigned numExtraArguments = d->numArguments - d->numParameters; - markStack.appendValues(reinterpret_cast<JSValue*>(d->extraArguments), numExtraArguments); - } - - markStack.append(d->callee); - - if (d->activation) - markStack.append(d->activation); -} - -void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize) -{ - if (UNLIKELY(d->overrodeLength)) { - unsigned length = min(get(exec, exec->propertyNames().length).toUInt32(exec), maxSize); - for (unsigned i = 0; i < length; i++) - buffer[i] = get(exec, i); - return; - } - - if (LIKELY(!d->deletedArguments)) { - unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize); - unsigned i = 0; - for (; i < parametersLength; ++i) - buffer[i] = d->registers[d->firstParameterIndex + i].jsValue(); - for (; i < d->numArguments; ++i) - buffer[i] = d->extraArguments[i - d->numParameters].jsValue(); - return; - } - - unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize); - unsigned i = 0; - for (; i < parametersLength; ++i) { - if (!d->deletedArguments[i]) - buffer[i] = d->registers[d->firstParameterIndex + i].jsValue(); - else - buffer[i] = get(exec, i); - } - for (; i < d->numArguments; ++i) { - if (!d->deletedArguments[i]) - buffer[i] = d->extraArguments[i - d->numParameters].jsValue(); - else - buffer[i] = get(exec, i); - } -} - -void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) -{ - if (UNLIKELY(d->overrodeLength)) { - unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec); - for (unsigned i = 0; i < length; i++) - args.append(get(exec, i)); - return; - } - - if (LIKELY(!d->deletedArguments)) { - if (LIKELY(!d->numParameters)) { - args.initialize(d->extraArguments, d->numArguments); - return; - } - - if (d->numParameters == d->numArguments) { - args.initialize(&d->registers[d->firstParameterIndex], d->numArguments); - return; - } - - unsigned parametersLength = min(d->numParameters, d->numArguments); - unsigned i = 0; - for (; i < parametersLength; ++i) - args.append(d->registers[d->firstParameterIndex + i].jsValue()); - for (; i < d->numArguments; ++i) - args.append(d->extraArguments[i - d->numParameters].jsValue()); - return; - } - - unsigned parametersLength = min(d->numParameters, d->numArguments); - unsigned i = 0; - for (; i < parametersLength; ++i) { - if (!d->deletedArguments[i]) - args.append(d->registers[d->firstParameterIndex + i].jsValue()); - else - args.append(get(exec, i)); - } - for (; i < d->numArguments; ++i) { - if (!d->deletedArguments[i]) - args.append(d->extraArguments[i - d->numParameters].jsValue()); - else - args.append(get(exec, i)); - } -} - -bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) -{ - if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { - if (i < d->numParameters) { - slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]); - } else - slot.setValue(d->extraArguments[i - d->numParameters].jsValue()); - return true; - } - - return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::number(i)), slot); -} - -void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) -{ - if (d->overrodeCaller) - return; - - d->overrodeCaller = true; - PropertyDescriptor descriptor; - JSValue thrower = createTypeErrorFunction(exec, "Unable to access caller of strict mode function"); - descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); - defineOwnProperty(exec, exec->propertyNames().caller, descriptor, false); -} - -void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec) -{ - if (d->overrodeCallee) - return; - - d->overrodeCallee = true; - PropertyDescriptor descriptor; - JSValue thrower = createTypeErrorFunction(exec, "Unable to access callee of strict mode function"); - descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); - defineOwnProperty(exec, exec->propertyNames().callee, descriptor, false); -} - -bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { - if (i < d->numParameters) { - slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]); - } else - slot.setValue(d->extraArguments[i - d->numParameters].jsValue()); - return true; - } - - if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) { - slot.setValue(jsNumber(d->numArguments)); - return true; - } - - if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { - if (!d->isStrictMode) { - slot.setValue(d->callee); - return true; - } - createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && d->isStrictMode) - createStrictModeCallerIfNecessary(exec); - - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { - if (i < d->numParameters) { - descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum); - } else - descriptor.setDescriptor(d->extraArguments[i - d->numParameters].jsValue(), DontEnum); - return true; - } - - if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) { - descriptor.setDescriptor(jsNumber(d->numArguments), DontEnum); - return true; - } - - if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { - if (!d->isStrictMode) { - descriptor.setDescriptor(d->callee, DontEnum); - return true; - } - createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && d->isStrictMode) - createStrictModeCallerIfNecessary(exec); - - return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - -void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - if (mode == IncludeDontEnumProperties) { - for (unsigned i = 0; i < d->numArguments; ++i) { - if (!d->deletedArguments || !d->deletedArguments[i]) - propertyNames.add(Identifier(exec, UString::number(i))); - } - propertyNames.add(exec->propertyNames().callee); - propertyNames.add(exec->propertyNames().length); - } - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot) -{ - if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { - if (i < d->numParameters) - d->registers[d->firstParameterIndex + i] = JSValue(value); - else - d->extraArguments[i - d->numParameters] = JSValue(value); - return; - } - - JSObject::put(exec, Identifier(exec, UString::number(i)), value, slot); -} - -void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { - if (i < d->numParameters) - d->registers[d->firstParameterIndex + i] = JSValue(value); - else - d->extraArguments[i - d->numParameters] = JSValue(value); - return; - } - - if (propertyName == exec->propertyNames().length && !d->overrodeLength) { - d->overrodeLength = true; - putDirect(propertyName, value, DontEnum); - return; - } - - if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) { - if (!d->isStrictMode) { - d->overrodeCallee = true; - putDirect(propertyName, value, DontEnum); - return; - } - createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && d->isStrictMode) - createStrictModeCallerIfNecessary(exec); - - JSObject::put(exec, propertyName, value, slot); -} - -bool Arguments::deleteProperty(ExecState* exec, unsigned i) -{ - if (i < d->numArguments) { - if (!d->deletedArguments) { - d->deletedArguments.set(new bool[d->numArguments]); - memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments); - } - if (!d->deletedArguments[i]) { - d->deletedArguments[i] = true; - return true; - } - } - - return JSObject::deleteProperty(exec, Identifier(exec, UString::number(i))); -} - -bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex && i < d->numArguments) { - if (!d->deletedArguments) { - d->deletedArguments.set(new bool[d->numArguments]); - memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments); - } - if (!d->deletedArguments[i]) { - d->deletedArguments[i] = true; - return true; - } - } - - if (propertyName == exec->propertyNames().length && !d->overrodeLength) { - d->overrodeLength = true; - return true; - } - - if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) { - if (!d->isStrictMode) { - d->overrodeCallee = true; - return true; - } - createStrictModeCalleeIfNecessary(exec); - } - - if (propertyName == exec->propertyNames().caller && !d->isStrictMode) - createStrictModeCallerIfNecessary(exec); - - return JSObject::deleteProperty(exec, propertyName); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h deleted file mode 100644 index 715a2ac..0000000 --- a/JavaScriptCore/runtime/Arguments.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Arguments_h -#define Arguments_h - -#include "JSActivation.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "Interpreter.h" -#include "ObjectConstructor.h" -#include "PrototypeFunction.h" - -namespace JSC { - - struct ArgumentsData : Noncopyable { - JSActivation* activation; - - unsigned numParameters; - ptrdiff_t firstParameterIndex; - unsigned numArguments; - - Register* registers; - OwnArrayPtr<Register> registerArray; - - Register* extraArguments; - OwnArrayPtr<bool> deletedArguments; - Register extraArgumentsFixedBuffer[4]; - - JSFunction* callee; - bool overrodeLength : 1; - bool overrodeCallee : 1; - bool overrodeCaller : 1; - bool isStrictMode : 1; - }; - - - class Arguments : public JSObject { - public: - // Use an enum because otherwise gcc insists on doing a memory - // read. - enum { MaxArguments = 0x10000 }; - - enum NoParametersType { NoParameters }; - - Arguments(CallFrame*); - Arguments(CallFrame*, NoParametersType); - virtual ~Arguments(); - - static const ClassInfo info; - - virtual void markChildren(MarkStack&); - - void fillArgList(ExecState*, MarkedArgumentBuffer&); - - uint32_t numProvidedArguments(ExecState* exec) const - { - if (UNLIKELY(d->overrodeLength)) - return get(exec, exec->propertyNames().length).toUInt32(exec); - return d->numArguments; - } - - void copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize); - void copyRegisters(); - bool isTornOff() const { return d->registerArray; } - void setActivation(JSActivation* activation) - { - d->activation = activation; - d->registers = &activation->registerAt(0); - } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; - - private: - void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - 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); - void createStrictModeCallerIfNecessary(ExecState*); - void createStrictModeCalleeIfNecessary(ExecState*); - - virtual const ClassInfo* classInfo() const { return &info; } - - void init(CallFrame*); - - OwnPtr<ArgumentsData> d; - }; - - Arguments* asArguments(JSValue); - - inline Arguments* asArguments(JSValue value) - { - ASSERT(asObject(value)->inherits(&Arguments::info)); - return static_cast<Arguments*>(asObject(value)); - } - - ALWAYS_INLINE void Arguments::getArgumentsData(CallFrame* callFrame, JSFunction*& function, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc) - { - function = asFunction(callFrame->callee()); - - int numParameters = function->jsExecutable()->parameterCount(); - argc = callFrame->argumentCountIncludingThis(); - - if (argc <= numParameters) - argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters; - else - argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc; - - argc -= 1; // - 1 to skip "this" - firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters; - } - - inline Arguments::Arguments(CallFrame* callFrame) - : JSObject(callFrame->lexicalGlobalObject()->argumentsStructure()) - , d(adoptPtr(new ArgumentsData)) - { - JSFunction* callee; - ptrdiff_t firstParameterIndex; - Register* argv; - int numArguments; - getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments); - - d->numParameters = callee->jsExecutable()->parameterCount(); - d->firstParameterIndex = firstParameterIndex; - d->numArguments = numArguments; - - d->activation = 0; - d->registers = callFrame->registers(); - - Register* extraArguments; - if (d->numArguments <= d->numParameters) - extraArguments = 0; - else { - unsigned numExtraArguments = d->numArguments - d->numParameters; - if (numExtraArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register)) - extraArguments = new Register[numExtraArguments]; - else - extraArguments = d->extraArgumentsFixedBuffer; - for (unsigned i = 0; i < numExtraArguments; ++i) - extraArguments[i] = argv[d->numParameters + i]; - } - - d->extraArguments = extraArguments; - - d->callee = callee; - d->overrodeLength = false; - d->overrodeCallee = false; - d->overrodeCaller = false; - d->isStrictMode = callFrame->codeBlock()->isStrictMode(); - if (d->isStrictMode) - copyRegisters(); - } - - inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) - : JSObject(callFrame->lexicalGlobalObject()->argumentsStructure()) - , d(adoptPtr(new ArgumentsData)) - { - ASSERT(!asFunction(callFrame->callee())->jsExecutable()->parameterCount()); - - unsigned numArguments = callFrame->argumentCount(); - - d->numParameters = 0; - d->numArguments = numArguments; - d->activation = 0; - - Register* extraArguments; - if (numArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register)) - extraArguments = new Register[numArguments]; - else - extraArguments = d->extraArgumentsFixedBuffer; - - Register* argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numArguments - 1; - for (unsigned i = 0; i < numArguments; ++i) - extraArguments[i] = argv[i]; - - d->extraArguments = extraArguments; - - d->callee = asFunction(callFrame->callee()); - d->overrodeLength = false; - d->overrodeCallee = false; - d->overrodeCaller = false; - d->isStrictMode = callFrame->codeBlock()->isStrictMode(); - if (d->isStrictMode) - copyRegisters(); - } - - inline void Arguments::copyRegisters() - { - ASSERT(!isTornOff()); - - if (!d->numParameters) - return; - - int registerOffset = d->numParameters + RegisterFile::CallFrameHeaderSize; - size_t registerArraySize = d->numParameters; - - Register* registerArray = new Register[registerArraySize]; - memcpy(registerArray, d->registers - registerOffset, registerArraySize * sizeof(Register)); - d->registerArray.set(registerArray); - d->registers = registerArray + registerOffset; - } - - // This JSActivation function is defined here so it can get at Arguments::setRegisters. - inline void JSActivation::copyRegisters() - { - ASSERT(!d()->registerArray); - - size_t numParametersMinusThis = d()->functionExecutable->parameterCount(); - size_t numVars = d()->functionExecutable->capturedVariableCount(); - size_t numLocals = numVars + numParametersMinusThis; - - if (!numLocals) - return; - - int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize; - size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize; - - Register* registerArray = copyRegisterArray(d()->registers - registerOffset, registerArraySize); - setRegisters(registerArray + registerOffset, registerArray); - } - -} // namespace JSC - -#endif // Arguments_h diff --git a/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp deleted file mode 100644 index 632d466..0000000 --- a/JavaScriptCore/runtime/ArrayConstructor.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2003 Peter Kelly (pmk@post.com) - * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "ArrayConstructor.h" - -#include "ArrayPrototype.h" -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSArray.h" -#include "JSFunction.h" -#include "Lookup.h" -#include "PrototypeFunction.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor); - -static EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*); - -ArrayConstructor::ArrayConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype, Structure* prototypeFunctionStructure) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, arrayPrototype->classInfo()->className)) -{ - // ECMA 15.4.3.1 Array.prototype - putDirectWithoutTransition(exec->propertyNames().prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly); - - // no. of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete); - - // ES5 - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum); -} - -static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args) -{ - // a single numeric argument denotes the array size (!) - if (args.size() == 1 && args.at(0).isNumber()) { - uint32_t n = args.at(0).toUInt32(exec); - if (n != args.at(0).toNumber(exec)) - return throwError(exec, createRangeError(exec, "Array size is not a small enough positive integer.")); - return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n, CreateInitialized); - } - - // otherwise the array is constructed with the arguments in it - return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), args); -} - -static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructArrayWithSizeQuirk(exec, args)); -} - -// ECMA 15.4.2 -ConstructType ArrayConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithArrayConstructor; - return ConstructTypeHost; -} - -static EncodedJSValue JSC_HOST_CALL callArrayConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructArrayWithSizeQuirk(exec, args)); -} - -// ECMA 15.6.1 -CallType ArrayConstructor::getCallData(CallData& callData) -{ - // equivalent to 'new Array(....)' - callData.native.function = callArrayConstructor; - return CallTypeHost; -} - -EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState* exec) -{ - return JSValue::encode(jsBoolean(exec->argument(0).inherits(&JSArray::info))); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ArrayConstructor.h b/JavaScriptCore/runtime/ArrayConstructor.h deleted file mode 100644 index 5e1408f..0000000 --- a/JavaScriptCore/runtime/ArrayConstructor.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ArrayConstructor_h -#define ArrayConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class ArrayPrototype; - - class ArrayConstructor : public InternalFunction { - public: - ArrayConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, ArrayPrototype*, Structure*); - - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - -} // namespace JSC - -#endif // ArrayConstructor_h diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp deleted file mode 100644 index ab0c3d4..0000000 --- a/JavaScriptCore/runtime/ArrayPrototype.cpp +++ /dev/null @@ -1,1098 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2003 Peter Kelly (pmk@post.com) - * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "ArrayPrototype.h" - -#include "CachedCall.h" -#include "CodeBlock.h" -#include "Interpreter.h" -#include "JIT.h" -#include "JSStringBuilder.h" -#include "Lookup.h" -#include "ObjectPrototype.h" -#include "Operations.h" -#include <algorithm> -#include <wtf/Assertions.h> -#include <wtf/HashSet.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype); - -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*); -static EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*); - -} - -#include "ArrayPrototype.lut.h" - -namespace JSC { - -static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, const CallData& callData) -{ - if (callType != CallTypeJS) - return false; - - FunctionExecutable* executable = callData.js.functionExecutable; - - JSObject* error = executable->compileForCall(exec, callData.js.scopeChain); - if (error) - return false; - - return executable->generatedBytecodeForCall().isNumericCompareFunction(); -} - -// ------------------------------ ArrayPrototype ---------------------------- - -const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::arrayTable}; - -/* Source for ArrayPrototype.lut.h -@begin arrayTable 16 - toString arrayProtoFuncToString DontEnum|Function 0 - toLocaleString arrayProtoFuncToLocaleString DontEnum|Function 0 - concat arrayProtoFuncConcat DontEnum|Function 1 - join arrayProtoFuncJoin DontEnum|Function 1 - pop arrayProtoFuncPop DontEnum|Function 0 - push arrayProtoFuncPush DontEnum|Function 1 - reverse arrayProtoFuncReverse DontEnum|Function 0 - shift arrayProtoFuncShift DontEnum|Function 0 - slice arrayProtoFuncSlice DontEnum|Function 2 - sort arrayProtoFuncSort DontEnum|Function 1 - splice arrayProtoFuncSplice DontEnum|Function 2 - unshift arrayProtoFuncUnShift DontEnum|Function 1 - every arrayProtoFuncEvery DontEnum|Function 1 - forEach arrayProtoFuncForEach DontEnum|Function 1 - some arrayProtoFuncSome DontEnum|Function 1 - indexOf arrayProtoFuncIndexOf DontEnum|Function 1 - lastIndexOf arrayProtoFuncLastIndexOf DontEnum|Function 1 - filter arrayProtoFuncFilter DontEnum|Function 1 - reduce arrayProtoFuncReduce DontEnum|Function 1 - reduceRight arrayProtoFuncReduceRight DontEnum|Function 1 - map arrayProtoFuncMap DontEnum|Function 1 -@end -*/ - -// ECMA 15.4.4 -ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : JSArray(structure) -{ - putAnonymousValue(0, globalObject); -} - -bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticFunctionSlot<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, slot); -} - -bool ArrayPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticFunctionDescriptor<JSArray>(exec, ExecState::arrayTable(exec), this, propertyName, descriptor); -} - -// ------------------------------ Array Functions ---------------------------- - -// Helper function -static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index) -{ - PropertySlot slot(obj); - if (!obj->getPropertySlot(exec, index, slot)) - return JSValue(); - return slot.getValue(exec, index); -} - -static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue value) -{ - PutPropertySlot slot; - obj->put(exec, propertyName, value, slot); -} - -static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0) -{ - JSValue value = exec->argument(argument); - if (value.isUndefined()) - return undefinedValue; - - double indexDouble = value.toInteger(exec); - if (indexDouble < 0) { - indexDouble += length; - return indexDouble < 0 ? 0 : static_cast<unsigned>(indexDouble); - } - return indexDouble > length ? length : static_cast<unsigned>(indexDouble); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - bool isRealArray = isJSArray(&exec->globalData(), thisValue); - if (!isRealArray && !thisValue.inherits(&JSArray::info)) - return throwVMTypeError(exec); - JSArray* thisObj = asArray(thisValue); - - HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; - if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) { - if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth) - return throwVMError(exec, createStackOverflowError(exec)); - } - - bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; - if (alreadyVisited) - return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoiding infinite recursion. - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned totalSize = length ? length - 1 : 0; -#if OS(SYMBIAN) - // Symbian has very limited stack size available. - // This function could be called recursively and allocating 1K on stack here cause - // stack overflow on Symbian devices. - Vector<RefPtr<StringImpl> > strBuffer(length); -#else - Vector<RefPtr<StringImpl>, 256> strBuffer(length); -#endif - for (unsigned k = 0; k < length; k++) { - JSValue element; - if (isRealArray && thisObj->canGetIndex(k)) - element = thisObj->getIndex(k); - else - element = thisObj->get(exec, k); - - if (element.isUndefinedOrNull()) - continue; - - UString str = element.toString(exec); - strBuffer[k] = str.impl(); - totalSize += str.length(); - - if (!strBuffer.data()) { - throwOutOfMemoryError(exec); - } - - if (exec->hadException()) - break; - } - arrayVisitedElements.remove(thisObj); - if (!totalSize) - return JSValue::encode(jsEmptyString(exec)); - Vector<UChar> buffer; - buffer.reserveCapacity(totalSize); - if (!buffer.data()) - return JSValue::encode(throwOutOfMemoryError(exec)); - - for (unsigned i = 0; i < length; i++) { - if (i) - buffer.append(','); - if (RefPtr<StringImpl> rep = strBuffer[i]) - buffer.append(rep->characters(), rep->length()); - } - ASSERT(buffer.size() == totalSize); - return JSValue::encode(jsString(exec, UString::adopt(buffer))); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&JSArray::info)) - return throwVMTypeError(exec); - JSObject* thisObj = asArray(thisValue); - - HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; - if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) { - if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth) - return throwVMError(exec, createStackOverflowError(exec)); - } - - bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; - if (alreadyVisited) - return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion. - - JSStringBuilder strBuffer; - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - for (unsigned k = 0; k < length; k++) { - if (k >= 1) - strBuffer.append(','); - - JSValue element = thisObj->get(exec, k); - if (!element.isUndefinedOrNull()) { - JSObject* o = element.toObject(exec); - JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString); - UString str; - CallData callData; - CallType callType = getCallData(conversionFunction, callData); - if (callType != CallTypeNone) - str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec); - else - str = element.toString(exec); - strBuffer.append(str); - } - } - arrayVisitedElements.remove(thisObj); - return JSValue::encode(strBuffer.build(exec)); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements; - if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) { - if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth) - return throwVMError(exec, createStackOverflowError(exec)); - } - - bool alreadyVisited = !arrayVisitedElements.add(thisObj).second; - if (alreadyVisited) - return JSValue::encode(jsEmptyString(exec)); // return an empty string, avoding infinite recursion. - - JSStringBuilder strBuffer; - - UString separator; - if (!exec->argument(0).isUndefined()) - separator = exec->argument(0).toString(exec); - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned k = 0; - if (isJSArray(&exec->globalData(), thisObj)) { - JSArray* array = asArray(thisObj); - - if (length) { - if (!array->canGetIndex(k)) - goto skipFirstLoop; - JSValue element = array->getIndex(k); - if (!element.isUndefinedOrNull()) - strBuffer.append(element.toString(exec)); - k++; - } - - if (separator.isNull()) { - for (; k < length; k++) { - if (!array->canGetIndex(k)) - break; - strBuffer.append(','); - JSValue element = array->getIndex(k); - if (!element.isUndefinedOrNull()) - strBuffer.append(element.toString(exec)); - } - } else { - for (; k < length; k++) { - if (!array->canGetIndex(k)) - break; - strBuffer.append(separator); - JSValue element = array->getIndex(k); - if (!element.isUndefinedOrNull()) - strBuffer.append(element.toString(exec)); - } - } - } - skipFirstLoop: - for (; k < length; k++) { - if (k >= 1) { - if (separator.isNull()) - strBuffer.append(','); - else - strBuffer.append(separator); - } - - JSValue element = thisObj->get(exec, k); - if (!element.isUndefinedOrNull()) - strBuffer.append(element.toString(exec)); - } - arrayVisitedElements.remove(thisObj); - return JSValue::encode(strBuffer.build(exec)); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - JSArray* arr = constructEmptyArray(exec); - unsigned n = 0; - JSValue curArg = thisValue.toThisObject(exec); - size_t i = 0; - size_t argCount = exec->argumentCount(); - while (1) { - if (curArg.inherits(&JSArray::info)) { - unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec); - JSObject* curObject = curArg.toObject(exec); - for (unsigned k = 0; k < length; ++k) { - if (JSValue v = getProperty(exec, curObject, k)) - arr->put(exec, n, v); - n++; - } - } else { - arr->put(exec, n, curArg); - n++; - } - if (i == argCount) - break; - curArg = (exec->argument(i)); - ++i; - } - arr->setLength(n); - return JSValue::encode(arr); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (isJSArray(&exec->globalData(), thisValue)) - return JSValue::encode(asArray(thisValue)->pop()); - - JSObject* thisObj = thisValue.toThisObject(exec); - JSValue result; - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (length == 0) { - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length)); - result = jsUndefined(); - } else { - result = thisObj->get(exec, length - 1); - thisObj->deleteProperty(exec, length - 1); - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); - } - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (isJSArray(&exec->globalData(), thisValue) && exec->argumentCount() == 1) { - JSArray* array = asArray(thisValue); - array->push(exec, exec->argument(0)); - return JSValue::encode(jsNumber(array->length())); - } - - JSObject* thisObj = thisValue.toThisObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - for (unsigned n = 0; n < exec->argumentCount(); n++) - thisObj->put(exec, length + n, exec->argument(n)); - length += exec->argumentCount(); - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length)); - return JSValue::encode(jsNumber(length)); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned middle = length / 2; - - for (unsigned k = 0; k < middle; k++) { - unsigned lk1 = length - k - 1; - JSValue obj2 = getProperty(exec, thisObj, lk1); - JSValue obj = getProperty(exec, thisObj, k); - - if (obj2) - thisObj->put(exec, k, obj2); - else - thisObj->deleteProperty(exec, k); - - if (obj) - thisObj->put(exec, lk1, obj); - else - thisObj->deleteProperty(exec, lk1); - } - return JSValue::encode(thisObj); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - JSValue result; - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (length == 0) { - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length)); - result = jsUndefined(); - } else { - result = thisObj->get(exec, 0); - if (isJSArray(&exec->globalData(), thisObj)) - ((JSArray *)thisObj)->shiftCount(exec, 1); - else { - for (unsigned k = 1; k < length; k++) { - if (JSValue obj = getProperty(exec, thisObj, k)) - thisObj->put(exec, k - 1, obj); - else - thisObj->deleteProperty(exec, k - 1); - } - thisObj->deleteProperty(exec, length - 1); - } - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); - } - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec) -{ - // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10 - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - // We return a new array - JSArray* resObj = constructEmptyArray(exec); - JSValue result = resObj; - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); - unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length); - - unsigned n = 0; - for (unsigned k = begin; k < end; k++, n++) { - if (JSValue v = getProperty(exec, thisObj, k)) - resObj->put(exec, n, v); - } - resObj->setLength(n); - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - - if (thisObj->classInfo() == &JSArray::info) { - if (isNumericCompareFunction(exec, 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 JSValue::encode(thisObj); - } - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - - if (!length) - return JSValue::encode(thisObj); - - // "Min" sort. Not the fastest, but definitely less code than heapsort - // or quicksort, and much less swapping than bubblesort/insertionsort. - for (unsigned i = 0; i < length - 1; ++i) { - JSValue iObj = thisObj->get(exec, i); - unsigned themin = i; - JSValue minObj = iObj; - for (unsigned j = i + 1; j < length; ++j) { - JSValue jObj = thisObj->get(exec, j); - double compareResult; - if (jObj.isUndefined()) - compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1) - else if (minObj.isUndefined()) - compareResult = -1; - else if (callType != CallTypeNone) { - MarkedArgumentBuffer l; - l.append(jObj); - l.append(minObj); - compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec); - } else - compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1; - - if (compareResult < 0) { - themin = j; - minObj = jObj; - } - } - // Swap themin and i - if (themin > i) { - thisObj->put(exec, i, minObj); - thisObj->put(exec, themin, iObj); - } - } - return JSValue::encode(thisObj); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - // 15.4.4.12 - - if (!exec->argumentCount()) - return JSValue::encode(constructEmptyArray(exec)); - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length); - - unsigned deleteCount = length - begin; - if (exec->argumentCount() > 1) { - double deleteDouble = exec->argument(1).toInteger(exec); - if (deleteDouble < 0) - deleteCount = 0; - else if (deleteDouble > length - begin) - deleteCount = length - begin; - else - deleteCount = static_cast<unsigned>(deleteDouble); - } - - JSArray* resObj = new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), deleteCount, CreateCompact); - JSValue result = resObj; - - for (unsigned k = 0; k < deleteCount; k++) - resObj->uncheckedSetIndex(k, getProperty(exec, thisObj, k + begin)); - - resObj->setLength(deleteCount); - - unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0); - if (additionalArgs != deleteCount) { - if (additionalArgs < deleteCount) { - if ((!begin) && (isJSArray(&exec->globalData(), thisObj))) - ((JSArray *)thisObj)->shiftCount(exec, deleteCount - additionalArgs); - else { - for (unsigned k = begin; k < length - deleteCount; ++k) { - if (JSValue v = getProperty(exec, thisObj, k + deleteCount)) - thisObj->put(exec, k + additionalArgs, v); - else - thisObj->deleteProperty(exec, k + additionalArgs); - } - for (unsigned k = length; k > length - deleteCount + additionalArgs; --k) - thisObj->deleteProperty(exec, k - 1); - } - } else { - if ((!begin) && (isJSArray(&exec->globalData(), thisObj))) - ((JSArray *)thisObj)->unshiftCount(exec, additionalArgs - deleteCount); - else { - for (unsigned k = length - deleteCount; k > begin; --k) { - if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1)) - thisObj->put(exec, k + additionalArgs - 1, obj); - else - thisObj->deleteProperty(exec, k + additionalArgs - 1); - } - } - } - } - for (unsigned k = 0; k < additionalArgs; ++k) - thisObj->put(exec, k + begin, exec->argument(k + 2)); - - putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs)); - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - // 15.4.4.13 - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned nrArgs = exec->argumentCount(); - if ((nrArgs) && (length)) { - if (isJSArray(&exec->globalData(), thisObj)) - ((JSArray *)thisObj)->unshiftCount(exec, nrArgs); - else { - for (unsigned k = length; k > 0; --k) { - if (JSValue v = getProperty(exec, thisObj, k - 1)) - thisObj->put(exec, k + nrArgs - 1, v); - else - thisObj->deleteProperty(exec, k + nrArgs - 1); - } - } - } - for (unsigned k = 0; k < nrArgs; ++k) - thisObj->put(exec, k, exec->argument(k)); - JSValue result = jsNumber(length + nrArgs); - putProperty(exec, thisObj, exec->propertyNames().length, result); - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); - JSArray* resultArray = constructEmptyArray(exec); - - unsigned filterIndex = 0; - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) { - JSFunction* f = asFunction(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - 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(k)); - cachedCall.setArgument(2, thisObj); - - JSValue result = cachedCall.call(); - if (result.toBoolean(exec)) - resultArray->put(exec, filterIndex++, v); - } - if (k == length) - return JSValue::encode(resultArray); - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - JSValue v = slot.getValue(exec, k); - - MarkedArgumentBuffer eachArguments; - - eachArguments.append(v); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - JSValue result = call(exec, function, callType, callData, applyThis, eachArguments); - - if (result.toBoolean(exec)) - resultArray->put(exec, filterIndex++, v); - } - return JSValue::encode(resultArray); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec); - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - - JSArray* resultArray = constructEmptyArray(exec, length); - unsigned k = 0; - if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) { - JSFunction* f = asFunction(function); - JSArray* array = asArray(thisObj); - CachedCall cachedCall(exec, f, 3); - 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(k)); - cachedCall.setArgument(2, thisObj); - - resultArray->JSArray::put(exec, k, cachedCall.call()); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - JSValue v = slot.getValue(exec, k); - - MarkedArgumentBuffer eachArguments; - - eachArguments.append(v); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - JSValue result = call(exec, function, callType, callData, applyThis, eachArguments); - resultArray->put(exec, k, result); - } - - return JSValue::encode(resultArray); -} - -// Documentation for these three is available at: -// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every -// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach -// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(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); - 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(k)); - cachedCall.setArgument(2, thisObj); - JSValue result = cachedCall.call(); - if (!result.toBoolean(cachedCall.newCallFrame(exec))) - return JSValue::encode(jsBoolean(false)); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - MarkedArgumentBuffer eachArguments; - - eachArguments.append(slot.getValue(exec, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); - - if (!predicateResult) { - result = jsBoolean(false); - break; - } - } - - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(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); - 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(k)); - cachedCall.setArgument(2, thisObj); - - cachedCall.call(); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(slot.getValue(exec, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - call(exec, function, callType, callData, applyThis, eachArguments); - } - return JSValue::encode(jsUndefined()); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(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); - 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(k)); - cachedCall.setArgument(2, thisObj); - JSValue result = cachedCall.call(); - if (result.toBoolean(cachedCall.newCallFrame(exec))) - return JSValue::encode(jsBoolean(true)); - } - } - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot(thisObj); - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - MarkedArgumentBuffer eachArguments; - eachArguments.append(slot.getValue(exec, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec); - - if (predicateResult) { - result = jsBoolean(true); - break; - } - } - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - unsigned i = 0; - JSValue rv; - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (!length && exec->argumentCount() == 1) - return throwVMTypeError(exec); - JSArray* array = 0; - if (isJSArray(&exec->globalData(), thisObj)) - array = asArray(thisObj); - - if (exec->argumentCount() >= 2) - rv = exec->argument(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 throwVMTypeError(exec); - i++; - } - - if (callType == CallTypeJS && array) { - CachedCall cachedCall(exec, asFunction(function), 4); - 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(i)); - cachedCall.setArgument(3, array); - rv = cachedCall.call(); - } - if (i == length) // only return if we reached the end of the array - return JSValue::encode(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(i)); - eachArguments.append(thisObj); - - rv = call(exec, function, callType, callData, jsNull(), eachArguments); - } - return JSValue::encode(rv); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - JSValue function = exec->argument(0); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - unsigned i = 0; - JSValue rv; - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (!length && exec->argumentCount() == 1) - return throwVMTypeError(exec); - JSArray* array = 0; - if (isJSArray(&exec->globalData(), thisObj)) - array = asArray(thisObj); - - if (exec->argumentCount() >= 2) - rv = exec->argument(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 throwVMTypeError(exec); - i++; - } - - if (callType == CallTypeJS && array) { - CachedCall cachedCall(exec, asFunction(function), 4); - 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(idx)); - cachedCall.setArgument(3, array); - rv = cachedCall.call(); - } - if (i == length) // only return if we reached the end of the array - return JSValue::encode(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(idx)); - eachArguments.append(thisObj); - - rv = call(exec, function, callType, callData, jsNull(), eachArguments); - } - return JSValue::encode(rv); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec) -{ - // JavaScript 1.5 Extension by Mozilla - // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length); - - JSValue searchElement = exec->argument(0); - for (; index < length; ++index) { - JSValue e = getProperty(exec, thisObj, index); - if (!e) - continue; - if (JSValue::strictEqual(exec, searchElement, e)) - return JSValue::encode(jsNumber(index)); - } - - return JSValue::encode(jsNumber(-1)); -} - -EncodedJSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec) -{ - // JavaScript 1.6 Extension by Mozilla - // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - - unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); - if (!length) - return JSValue::encode(jsNumber(-1)); - - unsigned index = length - 1; - JSValue fromValue = exec->argument(1); - if (!fromValue.isUndefined()) { - double fromDouble = fromValue.toInteger(exec); - if (fromDouble < 0) { - fromDouble += length; - if (fromDouble < 0) - return JSValue::encode(jsNumber(-1)); - } - if (fromDouble < length) - index = static_cast<unsigned>(fromDouble); - } - - JSValue searchElement = exec->argument(0); - do { - ASSERT(index < length); - JSValue e = getProperty(exec, thisObj, index); - if (!e) - continue; - if (JSValue::strictEqual(exec, searchElement, e)) - return JSValue::encode(jsNumber(index)); - } while (index--); - - return JSValue::encode(jsNumber(-1)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ArrayPrototype.h b/JavaScriptCore/runtime/ArrayPrototype.h deleted file mode 100644 index 42665e3..0000000 --- a/JavaScriptCore/runtime/ArrayPrototype.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ArrayPrototype_h -#define ArrayPrototype_h - -#include "JSArray.h" -#include "Lookup.h" - -namespace JSC { - - class ArrayPrototype : public JSArray { - public: - explicit ArrayPrototype(JSGlobalObject*, NonNullPassRefPtr<Structure>); - - bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned AnonymousSlotCount = JSArray::AnonymousSlotCount + 1; - }; - -} // namespace JSC - -#endif // ArrayPrototype_h diff --git a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h deleted file mode 100644 index 74089a5..0000000 --- a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h +++ /dev/null @@ -1,55 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BatchedTransitionOptimizer_h -#define BatchedTransitionOptimizer_h - -#include <wtf/Noncopyable.h> -#include "JSObject.h" - -namespace JSC { - - class BatchedTransitionOptimizer : public Noncopyable { - public: - BatchedTransitionOptimizer(JSObject* object) - : m_object(object) - { - if (!m_object->structure()->isDictionary()) - m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure())); - } - - ~BatchedTransitionOptimizer() - { - m_object->flattenDictionaryObject(); - } - - private: - JSObject* m_object; - }; - -} // namespace JSC - -#endif // BatchedTransitionOptimizer_h diff --git a/JavaScriptCore/runtime/BooleanConstructor.cpp b/JavaScriptCore/runtime/BooleanConstructor.cpp deleted file mode 100644 index 0167e03..0000000 --- a/JavaScriptCore/runtime/BooleanConstructor.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "BooleanConstructor.h" - -#include "BooleanPrototype.h" -#include "JSGlobalObject.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor); - -BooleanConstructor::BooleanConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, BooleanPrototype* booleanPrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, booleanPrototype->classInfo()->className)) -{ - putDirectWithoutTransition(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly); - - // no. of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum); -} - -// ECMA 15.6.2 -JSObject* constructBoolean(ExecState* exec, const ArgList& args) -{ - BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure()); - obj->setInternalValue(jsBoolean(args.at(0).toBoolean(exec))); - return obj; -} - -static EncodedJSValue JSC_HOST_CALL constructWithBooleanConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructBoolean(exec, args)); -} - -ConstructType BooleanConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithBooleanConstructor; - return ConstructTypeHost; -} - -// ECMA 15.6.1 -static EncodedJSValue JSC_HOST_CALL callBooleanConstructor(ExecState* exec) -{ - return JSValue::encode(jsBoolean(exec->argument(0).toBoolean(exec))); -} - -CallType BooleanConstructor::getCallData(CallData& callData) -{ - callData.native.function = callBooleanConstructor; - return CallTypeHost; -} - -JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue immediateBooleanValue) -{ - BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure()); - obj->setInternalValue(immediateBooleanValue); - return obj; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/BooleanConstructor.h b/JavaScriptCore/runtime/BooleanConstructor.h deleted file mode 100644 index 0f3efa7..0000000 --- a/JavaScriptCore/runtime/BooleanConstructor.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef BooleanConstructor_h -#define BooleanConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class BooleanPrototype; - - class BooleanConstructor : public InternalFunction { - public: - BooleanConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, BooleanPrototype*); - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - - JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue); - JSObject* constructBoolean(ExecState*, const ArgList&); - -} // namespace JSC - -#endif // BooleanConstructor_h diff --git a/JavaScriptCore/runtime/BooleanObject.cpp b/JavaScriptCore/runtime/BooleanObject.cpp deleted file mode 100644 index c9b3846..0000000 --- a/JavaScriptCore/runtime/BooleanObject.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "BooleanObject.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(BooleanObject); - -const ClassInfo BooleanObject::info = { "Boolean", 0, 0, 0 }; - -BooleanObject::BooleanObject(NonNullPassRefPtr<Structure> structure) - : JSWrapperObject(structure) -{ -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/BooleanObject.h b/JavaScriptCore/runtime/BooleanObject.h deleted file mode 100644 index 4b02acb..0000000 --- a/JavaScriptCore/runtime/BooleanObject.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef BooleanObject_h -#define BooleanObject_h - -#include "JSWrapperObject.h" - -namespace JSC { - - class BooleanObject : public JSWrapperObject { - public: - explicit BooleanObject(NonNullPassRefPtr<Structure>); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - }; - - BooleanObject* asBooleanObject(JSValue); - - inline BooleanObject* asBooleanObject(JSValue value) - { - ASSERT(asObject(value)->inherits(&BooleanObject::info)); - return static_cast<BooleanObject*>(asObject(value)); - } - -} // namespace JSC - -#endif // BooleanObject_h diff --git a/JavaScriptCore/runtime/BooleanPrototype.cpp b/JavaScriptCore/runtime/BooleanPrototype.cpp deleted file mode 100644 index 7ffd095..0000000 --- a/JavaScriptCore/runtime/BooleanPrototype.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "BooleanPrototype.h" - -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSFunction.h" -#include "JSString.h" -#include "ObjectPrototype.h" -#include "PrototypeFunction.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype); - -// Functions -static EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*); - -// ECMA 15.6.4 - -BooleanPrototype::BooleanPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure) - : BooleanObject(structure) -{ - setInternalValue(jsBoolean(false)); - - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum); -} - - -// ------------------------------ Functions -------------------------- - -// ECMA 15.6.4.2 + 15.6.4.3 - -EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue == jsBoolean(false)) - return JSValue::encode(jsNontrivialString(exec, "false")); - - if (thisValue == jsBoolean(true)) - return JSValue::encode(jsNontrivialString(exec, "true")); - - if (!thisValue.inherits(&BooleanObject::info)) - return throwVMTypeError(exec); - - if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false)) - return JSValue::encode(jsNontrivialString(exec, "false")); - - ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true)); - return JSValue::encode(jsNontrivialString(exec, "true")); -} - -EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isBoolean()) - return JSValue::encode(thisValue); - - if (!thisValue.inherits(&BooleanObject::info)) - return throwVMTypeError(exec); - - return JSValue::encode(asBooleanObject(thisValue)->internalValue()); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/BooleanPrototype.h b/JavaScriptCore/runtime/BooleanPrototype.h deleted file mode 100644 index ddadc43..0000000 --- a/JavaScriptCore/runtime/BooleanPrototype.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef BooleanPrototype_h -#define BooleanPrototype_h - -#include "BooleanObject.h" - -namespace JSC { - - class BooleanPrototype : public BooleanObject { - public: - BooleanPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure); - }; - -} // namespace JSC - -#endif // BooleanPrototype_h diff --git a/JavaScriptCore/runtime/CachedTranscendentalFunction.h b/JavaScriptCore/runtime/CachedTranscendentalFunction.h deleted file mode 100644 index 67c7af8..0000000 --- a/JavaScriptCore/runtime/CachedTranscendentalFunction.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010 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 CachedTranscendentalFunction_h -#define CachedTranscendentalFunction_h - -#include "JSValue.h" - -namespace JSC { - -extern const double NaN; - -typedef double (*TranscendentalFunctionPtr)(double); - -// CachedTranscendentalFunction provides a generic mechanism to cache results -// for pure functions with the signature "double func(double)", and where NaN -// maps to NaN. -template<TranscendentalFunctionPtr orignalFunction> -class CachedTranscendentalFunction { - struct CacheEntry { - double operand; - double result; - }; - -public: - CachedTranscendentalFunction() - : m_cache(0) - { - } - - ~CachedTranscendentalFunction() - { - if (m_cache) - fastFree(m_cache); - } - - JSValue operator() (double operand) - { - if (UNLIKELY(!m_cache)) - initialize(); - CacheEntry* entry = &m_cache[hash(operand)]; - - if (entry->operand == operand) - return jsDoubleNumber(entry->result); - double result = orignalFunction(operand); - entry->operand = operand; - entry->result = result; - return jsDoubleNumber(result); - } - -private: - void initialize() - { - // Lazily allocate the table, populate with NaN->NaN mapping. - m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry))); - for (unsigned x = 0; x < s_cacheSize; ++x) { - m_cache[x].operand = NaN; - m_cache[x].result = NaN; - } - } - - static unsigned hash(double d) - { - union doubleAndUInt64 { - double d; - uint32_t is[2]; - } u; - u.d = d; - - unsigned x = u.is[0] ^ u.is[1]; - x = (x >> 20) ^ (x >> 8); - return x & (s_cacheSize - 1); - } - - static const unsigned s_cacheSize = 0x1000; - CacheEntry* m_cache; -}; - -} - -#endif // CachedTranscendentalFunction_h diff --git a/JavaScriptCore/runtime/CallData.cpp b/JavaScriptCore/runtime/CallData.cpp deleted file mode 100644 index 018e2ca..0000000 --- a/JavaScriptCore/runtime/CallData.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "CallData.h" - -#include "Executable.h" -#include "Interpreter.h" -#include "JSFunction.h" - -namespace JSC { - -JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) -{ - ASSERT(callType == CallTypeJS || callType == CallTypeHost); - return exec->interpreter()->executeCall(exec, asObject(functionObject), callType, callData, thisValue, args); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/CallData.h b/JavaScriptCore/runtime/CallData.h deleted file mode 100644 index 32e1094..0000000 --- a/JavaScriptCore/runtime/CallData.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CallData_h -#define CallData_h - -#include "JSValue.h" -#include "NativeFunctionWrapper.h" - -namespace JSC { - - class ArgList; - class ExecState; - class FunctionExecutable; - class JSObject; - class ScopeChainNode; - - enum CallType { - CallTypeNone, - CallTypeHost, - CallTypeJS - }; - - typedef EncodedJSValue (JSC_HOST_CALL *NativeFunction)(ExecState*); - - union CallData { - struct { - NativeFunction function; - } native; - struct { - FunctionExecutable* functionExecutable; - ScopeChainNode* scopeChain; - } js; - }; - - JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&); - -} // namespace JSC - -#endif // CallData_h diff --git a/JavaScriptCore/runtime/ClassInfo.h b/JavaScriptCore/runtime/ClassInfo.h deleted file mode 100644 index acec4e7..0000000 --- a/JavaScriptCore/runtime/ClassInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ClassInfo_h -#define ClassInfo_h - -#include "CallFrame.h" - -namespace JSC { - - class HashEntry; - struct HashTable; - - struct ClassInfo { - /** - * A string denoting the class name. Example: "Window". - */ - const char* className; - - /** - * Pointer to the class information of the base class. - * 0L if there is none. - */ - const ClassInfo* parentClass; - /** - * Static hash-table of properties. - * For classes that can be used from multiple threads, it is accessed via a getter function that would typically return a pointer to thread-specific value. - */ - const HashTable* propHashTable(ExecState* exec) const - { - if (classPropHashTableGetterFunction) - return classPropHashTableGetterFunction(exec); - return staticPropHashTable; - } - - const HashTable* staticPropHashTable; - typedef const HashTable* (*ClassPropHashTableGetterFunction)(ExecState*); - const ClassPropHashTableGetterFunction classPropHashTableGetterFunction; - }; - -} // namespace JSC - -#endif // ClassInfo_h diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp deleted file mode 100644 index 38845ce..0000000 --- a/JavaScriptCore/runtime/Collector.cpp +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "Collector.h" - -#include "ArgList.h" -#include "CallFrame.h" -#include "CodeBlock.h" -#include "CollectorHeapIterator.h" -#include "GCActivityCallback.h" -#include "Interpreter.h" -#include "JSArray.h" -#include "JSGlobalObject.h" -#include "JSLock.h" -#include "JSONObject.h" -#include "JSString.h" -#include "JSValue.h" -#include "JSZombie.h" -#include "MarkStack.h" -#include "Nodes.h" -#include "Tracing.h" -#include <algorithm> -#include <limits.h> -#include <setjmp.h> -#include <stdlib.h> -#include <wtf/FastMalloc.h> -#include <wtf/HashCountedSet.h> -#include <wtf/WTFThreadData.h> -#include <wtf/UnusedParam.h> -#include <wtf/VMTags.h> - -#if OS(DARWIN) - -#include <mach/mach_init.h> -#include <mach/mach_port.h> -#include <mach/task.h> -#include <mach/thread_act.h> -#include <mach/vm_map.h> - -#elif OS(WINDOWS) - -#include <windows.h> -#include <malloc.h> - -#elif OS(HAIKU) - -#include <OS.h> - -#elif OS(UNIX) - -#include <stdlib.h> -#if !OS(HAIKU) -#include <sys/mman.h> -#endif -#include <unistd.h> - -#if OS(SOLARIS) -#include <thread.h> -#else -#include <pthread.h> -#endif - -#if HAVE(PTHREAD_NP_H) -#include <pthread_np.h> -#endif - -#if OS(QNX) -#include <fcntl.h> -#include <sys/procfs.h> -#include <stdio.h> -#include <errno.h> -#endif - -#endif - -#define COLLECT_ON_EVERY_ALLOCATION 0 - -using std::max; - -namespace JSC { - -// tunable parameters - -const size_t GROWTH_FACTOR = 2; -const size_t LOW_WATER_FACTOR = 4; -const size_t ALLOCATIONS_PER_COLLECTION = 3600; -// This value has to be a macro to be used in max() without introducing -// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>. -#define MIN_ARRAY_SIZE (static_cast<size_t>(14)) - -#if ENABLE(JSC_MULTIPLE_THREADS) - -#if OS(DARWIN) -typedef mach_port_t PlatformThread; -#elif OS(WINDOWS) -typedef HANDLE PlatformThread; -#endif - -class Heap::Thread { -public: - Thread(pthread_t pthread, const PlatformThread& platThread, void* base) - : posixThread(pthread) - , platformThread(platThread) - , stackBase(base) - { - } - - Thread* next; - pthread_t posixThread; - PlatformThread platformThread; - void* stackBase; -}; - -#endif - -Heap::Heap(JSGlobalData* globalData) - : m_markListSet(0) -#if ENABLE(JSC_MULTIPLE_THREADS) - , m_registeredThreads(0) - , m_currentThreadRegistrar(0) -#endif - , m_globalData(globalData) -{ - ASSERT(globalData); - memset(&m_heap, 0, sizeof(CollectorHeap)); - allocateBlock(); - m_activityCallback = DefaultGCActivityCallback::create(this); - (*m_activityCallback)(); -} - -Heap::~Heap() -{ - // The destroy function must already have been called, so assert this. - ASSERT(!m_globalData); -} - -void Heap::destroy() -{ - JSLock lock(SilenceAssertionsOnly); - - if (!m_globalData) - return; - - ASSERT(!m_globalData->dynamicGlobalObject); - ASSERT(!isBusy()); - - // The global object is not GC protected at this point, so sweeping may delete it - // (and thus the global data) before other objects that may use the global data. - RefPtr<JSGlobalData> protect(m_globalData); - - delete m_markListSet; - m_markListSet = 0; - - freeBlocks(); - -#if ENABLE(JSC_MULTIPLE_THREADS) - if (m_currentThreadRegistrar) { - int error = pthread_key_delete(m_currentThreadRegistrar); - ASSERT_UNUSED(error, !error); - } - - MutexLocker registeredThreadsLock(m_registeredThreadsMutex); - for (Heap::Thread* t = m_registeredThreads; t;) { - Heap::Thread* next = t->next; - delete t; - t = next; - } -#endif - m_globalData = 0; -} - -NEVER_INLINE CollectorBlock* Heap::allocateBlock() -{ - PageAllocationAligned allocation = PageAllocationAligned::allocate(BLOCK_SIZE, BLOCK_SIZE, OSAllocator::JSGCHeapPages); - CollectorBlock* block = static_cast<CollectorBlock*>(allocation.base()); - if (!block) - CRASH(); - - // Initialize block. - - block->heap = this; - clearMarkBits(block); - - Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get(); - for (size_t i = 0; i < HeapConstants::cellsPerBlock; ++i) - new (&block->cells[i]) JSCell(dummyMarkableCellStructure); - - // Add block to blocks vector. - - size_t numBlocks = m_heap.numBlocks; - if (m_heap.usedBlocks == numBlocks) { - static const size_t maxNumBlocks = ULONG_MAX / sizeof(PageAllocationAligned) / GROWTH_FACTOR; - if (numBlocks > maxNumBlocks) - CRASH(); - numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR); - m_heap.numBlocks = numBlocks; - m_heap.blocks = static_cast<PageAllocationAligned*>(fastRealloc(m_heap.blocks, numBlocks * sizeof(PageAllocationAligned))); - } - m_heap.blocks[m_heap.usedBlocks++] = allocation; - - return block; -} - -NEVER_INLINE void Heap::freeBlock(size_t block) -{ - m_heap.didShrink = true; - - ObjectIterator it(m_heap, block); - ObjectIterator end(m_heap, block + 1); - for ( ; it != end; ++it) - (*it)->~JSCell(); - m_heap.blocks[block].deallocate(); - - // swap with the last block so we compact as we go - m_heap.blocks[block] = m_heap.blocks[m_heap.usedBlocks - 1]; - m_heap.usedBlocks--; - - if (m_heap.numBlocks > MIN_ARRAY_SIZE && m_heap.usedBlocks < m_heap.numBlocks / LOW_WATER_FACTOR) { - m_heap.numBlocks = m_heap.numBlocks / GROWTH_FACTOR; - m_heap.blocks = static_cast<PageAllocationAligned*>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(PageAllocationAligned))); - } -} - -void Heap::freeBlocks() -{ - ProtectCountSet protectedValuesCopy = m_protectedValues; - - clearMarkBits(); - ProtectCountSet::iterator protectedValuesEnd = protectedValuesCopy.end(); - for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it) - markCell(it->first); - - m_heap.nextCell = 0; - m_heap.nextBlock = 0; - DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell); - DeadObjectIterator end(m_heap, m_heap.usedBlocks); - for ( ; it != end; ++it) - (*it)->~JSCell(); - - ASSERT(!protectedObjectCount()); - - protectedValuesEnd = protectedValuesCopy.end(); - for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it) - it->first->~JSCell(); - - for (size_t block = 0; block < m_heap.usedBlocks; ++block) - m_heap.blocks[block].deallocate(); - - fastFree(m_heap.blocks); - - memset(&m_heap, 0, sizeof(CollectorHeap)); -} - -void Heap::recordExtraCost(size_t cost) -{ - // Our frequency of garbage collection tries to balance memory use against speed - // by collecting based on the number of newly created values. However, for values - // that hold on to a great deal of memory that's not in the form of other JS values, - // that is not good enough - in some cases a lot of those objects can pile up and - // use crazy amounts of memory without a GC happening. So we track these extra - // memory costs. Only unusually large objects are noted, and we only keep track - // of this extra cost until the next GC. In garbage collected languages, most values - // are either very short lived temporaries, or have extremely long lifetimes. So - // if a large value survives one garbage collection, there is not much point to - // collecting more frequently as long as it stays alive. - - if (m_heap.extraCost > maxExtraCost && m_heap.extraCost > m_heap.usedBlocks * BLOCK_SIZE / 2) { - // If the last iteration through the heap deallocated blocks, we need - // to clean up remaining garbage before marking. Otherwise, the conservative - // marking mechanism might follow a pointer to unmapped memory. - if (m_heap.didShrink) - sweep(); - reset(); - } - m_heap.extraCost += cost; -} - -void* Heap::allocate(size_t s) -{ - ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable()); - typedef HeapConstants::Block Block; - typedef HeapConstants::Cell Cell; - - ASSERT(JSLock::lockCount() > 0); - ASSERT(JSLock::currentThreadIsHoldingLock()); - ASSERT_UNUSED(s, s <= HeapConstants::cellSize); - - ASSERT(m_heap.operationInProgress == NoOperation); - -#if COLLECT_ON_EVERY_ALLOCATION - collectAllGarbage(); - ASSERT(m_heap.operationInProgress == NoOperation); -#endif - -allocate: - - // Fast case: find the next garbage cell and recycle it. - - do { - ASSERT(m_heap.nextBlock < m_heap.usedBlocks); - Block* block = m_heap.collectorBlock(m_heap.nextBlock); - do { - ASSERT(m_heap.nextCell < HeapConstants::cellsPerBlock); - if (!block->marked.get(m_heap.nextCell)) { // Always false for the last cell in the block - Cell* cell = &block->cells[m_heap.nextCell]; - - m_heap.operationInProgress = Allocation; - JSCell* imp = reinterpret_cast<JSCell*>(cell); - imp->~JSCell(); - m_heap.operationInProgress = NoOperation; - - ++m_heap.nextCell; - return cell; - } - block->marked.advanceToNextPossibleFreeCell(m_heap.nextCell); - } while (m_heap.nextCell != HeapConstants::cellsPerBlock); - m_heap.nextCell = 0; - } while (++m_heap.nextBlock != m_heap.usedBlocks); - - // Slow case: reached the end of the heap. Mark live objects and start over. - - reset(); - goto allocate; -} - -void Heap::resizeBlocks() -{ - m_heap.didShrink = false; - - size_t usedCellCount = markedCells(); - size_t minCellCount = usedCellCount + max(ALLOCATIONS_PER_COLLECTION, usedCellCount); - size_t minBlockCount = (minCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock; - - size_t maxCellCount = 1.25f * minCellCount; - size_t maxBlockCount = (maxCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock; - - if (m_heap.usedBlocks < minBlockCount) - growBlocks(minBlockCount); - else if (m_heap.usedBlocks > maxBlockCount) - shrinkBlocks(maxBlockCount); -} - -void Heap::growBlocks(size_t neededBlocks) -{ - ASSERT(m_heap.usedBlocks < neededBlocks); - while (m_heap.usedBlocks < neededBlocks) - allocateBlock(); -} - -void Heap::shrinkBlocks(size_t neededBlocks) -{ - ASSERT(m_heap.usedBlocks > neededBlocks); - - // Clear the always-on last bit, so isEmpty() isn't fooled by it. - for (size_t i = 0; i < m_heap.usedBlocks; ++i) - m_heap.collectorBlock(i)->marked.clear(HeapConstants::cellsPerBlock - 1); - - for (size_t i = 0; i != m_heap.usedBlocks && m_heap.usedBlocks != neededBlocks; ) { - if (m_heap.collectorBlock(i)->marked.isEmpty()) { - freeBlock(i); - } else - ++i; - } - - // Reset the always-on last bit. - for (size_t i = 0; i < m_heap.usedBlocks; ++i) - m_heap.collectorBlock(i)->marked.set(HeapConstants::cellsPerBlock - 1); -} - -#if ENABLE(JSC_MULTIPLE_THREADS) - -static inline PlatformThread getCurrentPlatformThread() -{ -#if OS(DARWIN) - return pthread_mach_thread_np(pthread_self()); -#elif OS(WINDOWS) - return pthread_getw32threadhandle_np(pthread_self()); -#endif -} - -void Heap::makeUsableFromMultipleThreads() -{ - if (m_currentThreadRegistrar) - return; - - int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread); - if (error) - CRASH(); -} - -void Heap::registerThread() -{ - ASSERT(!m_globalData->exclusiveThread || m_globalData->exclusiveThread == currentThread()); - - if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar)) - return; - - pthread_setspecific(m_currentThreadRegistrar, this); - Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), m_globalData->stack().origin()); - - MutexLocker lock(m_registeredThreadsMutex); - - thread->next = m_registeredThreads; - m_registeredThreads = thread; -} - -void Heap::unregisterThread(void* p) -{ - if (p) - static_cast<Heap*>(p)->unregisterThread(); -} - -void Heap::unregisterThread() -{ - pthread_t currentPosixThread = pthread_self(); - - MutexLocker lock(m_registeredThreadsMutex); - - if (pthread_equal(currentPosixThread, m_registeredThreads->posixThread)) { - Thread* t = m_registeredThreads; - m_registeredThreads = m_registeredThreads->next; - delete t; - } else { - Heap::Thread* last = m_registeredThreads; - Heap::Thread* t; - for (t = m_registeredThreads->next; t; t = t->next) { - if (pthread_equal(t->posixThread, currentPosixThread)) { - last->next = t->next; - break; - } - last = t; - } - ASSERT(t); // If t is NULL, we never found ourselves in the list. - delete t; - } -} - -#else // ENABLE(JSC_MULTIPLE_THREADS) - -void Heap::registerThread() -{ -} - -#endif - -inline bool isPointerAligned(void* p) -{ - return (((intptr_t)(p) & (sizeof(char*) - 1)) == 0); -} - -// Cell size needs to be a power of two for isPossibleCell to be valid. -COMPILE_ASSERT(sizeof(CollectorCell) % 2 == 0, Collector_cell_size_is_power_of_two); - -static inline bool isCellAligned(void *p) -{ - return (((intptr_t)(p) & CELL_MASK) == 0); -} - -static inline bool isPossibleCell(void* p) -{ - return isCellAligned(p) && p; -} - -void Heap::markConservatively(MarkStack& markStack, void* start, void* end) -{ -#if OS(WINCE) - if (start > end) { - void* tmp = start; - start = end; - end = tmp; - } -#else - ASSERT(start <= end); -#endif - - ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000); - ASSERT(isPointerAligned(start)); - ASSERT(isPointerAligned(end)); - - char** p = static_cast<char**>(start); - char** e = static_cast<char**>(end); - - while (p != e) { - char* x = *p++; - if (isPossibleCell(x)) { - size_t usedBlocks; - uintptr_t xAsBits = reinterpret_cast<uintptr_t>(x); - xAsBits &= CELL_ALIGN_MASK; - - uintptr_t offset = xAsBits & BLOCK_OFFSET_MASK; - const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1); - if (offset > lastCellOffset) - continue; - - CollectorBlock* blockAddr = reinterpret_cast<CollectorBlock*>(xAsBits - offset); - usedBlocks = m_heap.usedBlocks; - for (size_t block = 0; block < usedBlocks; block++) { - if (m_heap.collectorBlock(block) != blockAddr) - continue; - markStack.append(reinterpret_cast<JSCell*>(xAsBits)); - } - } - } -} - -void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal(MarkStack& markStack) -{ - markConservatively(markStack, m_globalData->stack().current(), m_globalData->stack().origin()); - markStack.drain(); -} - -#if COMPILER(GCC) -#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*)))) -#else -#define REGISTER_BUFFER_ALIGNMENT -#endif - -void Heap::markCurrentThreadConservatively(MarkStack& markStack) -{ - // setjmp forces volatile registers onto the stack - jmp_buf registers REGISTER_BUFFER_ALIGNMENT; -#if COMPILER(MSVC) -#pragma warning(push) -#pragma warning(disable: 4611) -#endif - setjmp(registers); -#if COMPILER(MSVC) -#pragma warning(pop) -#endif - - markCurrentThreadConservativelyInternal(markStack); -} - -#if ENABLE(JSC_MULTIPLE_THREADS) - -static inline void suspendThread(const PlatformThread& platformThread) -{ -#if OS(DARWIN) - thread_suspend(platformThread); -#elif OS(WINDOWS) - SuspendThread(platformThread); -#else -#error Need a way to suspend threads on this platform -#endif -} - -static inline void resumeThread(const PlatformThread& platformThread) -{ -#if OS(DARWIN) - thread_resume(platformThread); -#elif OS(WINDOWS) - ResumeThread(platformThread); -#else -#error Need a way to resume threads on this platform -#endif -} - -typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit - -#if OS(DARWIN) - -#if CPU(X86) -typedef i386_thread_state_t PlatformThreadRegisters; -#elif CPU(X86_64) -typedef x86_thread_state64_t PlatformThreadRegisters; -#elif CPU(PPC) -typedef ppc_thread_state_t PlatformThreadRegisters; -#elif CPU(PPC64) -typedef ppc_thread_state64_t PlatformThreadRegisters; -#elif CPU(ARM) -typedef arm_thread_state_t PlatformThreadRegisters; -#else -#error Unknown Architecture -#endif - -#elif OS(WINDOWS) && CPU(X86) -typedef CONTEXT PlatformThreadRegisters; -#else -#error Need a thread register struct for this platform -#endif - -static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs) -{ -#if OS(DARWIN) - -#if CPU(X86) - unsigned user_count = sizeof(regs)/sizeof(int); - thread_state_flavor_t flavor = i386_THREAD_STATE; -#elif CPU(X86_64) - unsigned user_count = x86_THREAD_STATE64_COUNT; - thread_state_flavor_t flavor = x86_THREAD_STATE64; -#elif CPU(PPC) - unsigned user_count = PPC_THREAD_STATE_COUNT; - thread_state_flavor_t flavor = PPC_THREAD_STATE; -#elif CPU(PPC64) - unsigned user_count = PPC_THREAD_STATE64_COUNT; - thread_state_flavor_t flavor = PPC_THREAD_STATE64; -#elif CPU(ARM) - unsigned user_count = ARM_THREAD_STATE_COUNT; - thread_state_flavor_t flavor = ARM_THREAD_STATE; -#else -#error Unknown Architecture -#endif - - kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)®s, &user_count); - if (result != KERN_SUCCESS) { - WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, - "JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.", result); - CRASH(); - } - return user_count * sizeof(usword_t); -// end OS(DARWIN) - -#elif OS(WINDOWS) && CPU(X86) - regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS; - GetThreadContext(platformThread, ®s); - return sizeof(CONTEXT); -#else -#error Need a way to get thread registers on this platform -#endif -} - -static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) -{ -#if OS(DARWIN) - -#if __DARWIN_UNIX03 - -#if CPU(X86) - return reinterpret_cast<void*>(regs.__esp); -#elif CPU(X86_64) - return reinterpret_cast<void*>(regs.__rsp); -#elif CPU(PPC) || CPU(PPC64) - return reinterpret_cast<void*>(regs.__r1); -#elif CPU(ARM) - return reinterpret_cast<void*>(regs.__sp); -#else -#error Unknown Architecture -#endif - -#else // !__DARWIN_UNIX03 - -#if CPU(X86) - return reinterpret_cast<void*>(regs.esp); -#elif CPU(X86_64) - return reinterpret_cast<void*>(regs.rsp); -#elif CPU(PPC) || CPU(PPC64) - return reinterpret_cast<void*>(regs.r1); -#else -#error Unknown Architecture -#endif - -#endif // __DARWIN_UNIX03 - -// end OS(DARWIN) -#elif CPU(X86) && OS(WINDOWS) - return reinterpret_cast<void*>((uintptr_t) regs.Esp); -#else -#error Need a way to get the stack pointer for another thread on this platform -#endif -} - -void Heap::markOtherThreadConservatively(MarkStack& markStack, Thread* thread) -{ - suspendThread(thread->platformThread); - - PlatformThreadRegisters regs; - size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs); - - // mark the thread's registers - markConservatively(markStack, static_cast<void*>(®s), static_cast<void*>(reinterpret_cast<char*>(®s) + regSize)); - markStack.drain(); - - void* stackPointer = otherThreadStackPointer(regs); - markConservatively(markStack, stackPointer, thread->stackBase); - markStack.drain(); - - resumeThread(thread->platformThread); -} - -#endif - -void Heap::markStackObjectsConservatively(MarkStack& markStack) -{ - markCurrentThreadConservatively(markStack); - -#if ENABLE(JSC_MULTIPLE_THREADS) - - if (m_currentThreadRegistrar) { - - MutexLocker lock(m_registeredThreadsMutex); - -#ifndef NDEBUG - // Forbid malloc during the mark phase. Marking a thread suspends it, so - // a malloc inside markChildren() would risk a deadlock with a thread that had been - // suspended while holding the malloc lock. - fastMallocForbid(); -#endif - // It is safe to access the registeredThreads list, because we earlier asserted that locks are being held, - // and since this is a shared heap, they are real locks. - for (Thread* thread = m_registeredThreads; thread; thread = thread->next) { - if (!pthread_equal(thread->posixThread, pthread_self())) - markOtherThreadConservatively(markStack, thread); - } -#ifndef NDEBUG - fastMallocAllow(); -#endif - } -#endif -} - -void Heap::updateWeakGCHandles() -{ - for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i) - weakGCHandlePool(i)->update(); -} - -void WeakGCHandlePool::update() -{ - for (unsigned i = 1; i < WeakGCHandlePool::numPoolEntries; ++i) { - if (m_entries[i].isValidPtr()) { - JSCell* cell = m_entries[i].get(); - if (!cell || !Heap::isCellMarked(cell)) - m_entries[i].invalidate(); - } - } -} - -WeakGCHandle* Heap::addWeakGCHandle(JSCell* ptr) -{ - for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i) - if (!weakGCHandlePool(i)->isFull()) - return weakGCHandlePool(i)->allocate(ptr); - - PageAllocationAligned allocation = PageAllocationAligned::allocate(WeakGCHandlePool::poolSize, WeakGCHandlePool::poolSize, OSAllocator::JSGCHeapPages); - m_weakGCHandlePools.append(allocation); - - WeakGCHandlePool* pool = new (allocation.base()) WeakGCHandlePool(); - return pool->allocate(ptr); -} - -void Heap::protect(JSValue k) -{ - ASSERT(k); - ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance()); - - if (!k.isCell()) - return; - - m_protectedValues.add(k.asCell()); -} - -bool Heap::unprotect(JSValue k) -{ - ASSERT(k); - ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance()); - - if (!k.isCell()) - return false; - - return m_protectedValues.remove(k.asCell()); -} - -void Heap::markProtectedObjects(MarkStack& markStack) -{ - ProtectCountSet::iterator end = m_protectedValues.end(); - for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) { - markStack.append(it->first); - markStack.drain(); - } -} - -void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector) -{ - m_tempSortingVectors.append(tempVector); -} - -void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector) -{ - ASSERT_UNUSED(tempVector, tempVector == m_tempSortingVectors.last()); - m_tempSortingVectors.removeLast(); -} - -void Heap::markTempSortVectors(MarkStack& markStack) -{ - typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors; - - VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end(); - for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) { - Vector<ValueStringPair>* tempSortingVector = *it; - - Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end(); - for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt) - if (vectorIt->first) - markStack.append(vectorIt->first); - markStack.drain(); - } -} - -void Heap::clearMarkBits() -{ - for (size_t i = 0; i < m_heap.usedBlocks; ++i) - clearMarkBits(m_heap.collectorBlock(i)); -} - -void Heap::clearMarkBits(CollectorBlock* block) -{ - // allocate assumes that the last cell in every block is marked. - block->marked.clearAll(); - block->marked.set(HeapConstants::cellsPerBlock - 1); -} - -size_t Heap::markedCells(size_t startBlock, size_t startCell) const -{ - ASSERT(startBlock <= m_heap.usedBlocks); - ASSERT(startCell < HeapConstants::cellsPerBlock); - - if (startBlock >= m_heap.usedBlocks) - return 0; - - size_t result = 0; - result += m_heap.collectorBlock(startBlock)->marked.count(startCell); - for (size_t i = startBlock + 1; i < m_heap.usedBlocks; ++i) - result += m_heap.collectorBlock(i)->marked.count(); - - return result; -} - -void Heap::sweep() -{ - ASSERT(m_heap.operationInProgress == NoOperation); - if (m_heap.operationInProgress != NoOperation) - CRASH(); - m_heap.operationInProgress = Collection; - -#if !ENABLE(JSC_ZOMBIES) - Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get(); -#endif - - DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell); - DeadObjectIterator end(m_heap, m_heap.usedBlocks); - for ( ; it != end; ++it) { - JSCell* cell = *it; -#if ENABLE(JSC_ZOMBIES) - if (!cell->isZombie()) { - const ClassInfo* info = cell->classInfo(); - cell->~JSCell(); - new (cell) JSZombie(info, JSZombie::leakedZombieStructure()); - Heap::markCell(cell); - } -#else - cell->~JSCell(); - // Callers of sweep assume it's safe to mark any cell in the heap. - new (cell) JSCell(dummyMarkableCellStructure); -#endif - } - - m_heap.operationInProgress = NoOperation; -} - -void Heap::markRoots() -{ -#ifndef NDEBUG - if (m_globalData->isSharedInstance()) { - ASSERT(JSLock::lockCount() > 0); - ASSERT(JSLock::currentThreadIsHoldingLock()); - } -#endif - - ASSERT(m_heap.operationInProgress == NoOperation); - if (m_heap.operationInProgress != NoOperation) - CRASH(); - - m_heap.operationInProgress = Collection; - - MarkStack& markStack = m_globalData->markStack; - - // Reset mark bits. - clearMarkBits(); - - // Mark stack roots. - markStackObjectsConservatively(markStack); - m_globalData->interpreter->registerFile().markCallFrames(markStack, this); - - // Mark explicitly registered roots. - markProtectedObjects(markStack); - - // Mark temporary vector for Array sorting - markTempSortVectors(markStack); - - // Mark misc. other roots. - if (m_markListSet && m_markListSet->size()) - MarkedArgumentBuffer::markLists(markStack, *m_markListSet); - if (m_globalData->exception) - markStack.append(m_globalData->exception); - if (m_globalData->firstStringifierToMark) - JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark); - - // Mark the small strings cache last, since it will clear itself if nothing - // else has marked it. - m_globalData->smallStrings.markChildren(markStack); - - markStack.drain(); - markStack.compact(); - - updateWeakGCHandles(); - - m_heap.operationInProgress = NoOperation; -} - -size_t Heap::objectCount() const -{ - return m_heap.nextBlock * HeapConstants::cellsPerBlock // allocated full blocks - + m_heap.nextCell // allocated cells in current block - + markedCells(m_heap.nextBlock, m_heap.nextCell) // marked cells in remainder of m_heap - - m_heap.usedBlocks; // 1 cell per block is a dummy sentinel -} - -void Heap::addToStatistics(Heap::Statistics& statistics) const -{ - statistics.size += m_heap.usedBlocks * BLOCK_SIZE; - statistics.free += m_heap.usedBlocks * BLOCK_SIZE - (objectCount() * HeapConstants::cellSize); -} - -Heap::Statistics Heap::statistics() const -{ - Statistics statistics = { 0, 0 }; - addToStatistics(statistics); - return statistics; -} - -size_t Heap::size() const -{ - return m_heap.usedBlocks * BLOCK_SIZE; -} - -size_t Heap::globalObjectCount() -{ - size_t count = 0; - if (JSGlobalObject* head = m_globalData->head) { - JSGlobalObject* o = head; - do { - ++count; - o = o->next(); - } while (o != head); - } - return count; -} - -size_t Heap::protectedGlobalObjectCount() -{ - size_t count = 0; - if (JSGlobalObject* head = m_globalData->head) { - JSGlobalObject* o = head; - do { - if (m_protectedValues.contains(o)) - ++count; - o = o->next(); - } while (o != head); - } - - return count; -} - -size_t Heap::protectedObjectCount() -{ - return m_protectedValues.size(); -} - -static const char* typeName(JSCell* cell) -{ - if (cell->isString()) - return "string"; - if (cell->isGetterSetter()) - return "Getter-Setter"; - if (cell->isAPIValueWrapper()) - return "API wrapper"; - if (cell->isPropertyNameIterator()) - return "For-in iterator"; - if (!cell->isObject()) - return "[empty cell]"; - const ClassInfo* info = cell->classInfo(); - return info ? info->className : "Object"; -} - -HashCountedSet<const char*>* Heap::protectedObjectTypeCounts() -{ - HashCountedSet<const char*>* counts = new HashCountedSet<const char*>; - - ProtectCountSet::iterator end = m_protectedValues.end(); - for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) - counts->add(typeName(it->first)); - - return counts; -} - -HashCountedSet<const char*>* Heap::objectTypeCounts() -{ - HashCountedSet<const char*>* counts = new HashCountedSet<const char*>; - - LiveObjectIterator it = primaryHeapBegin(); - LiveObjectIterator heapEnd = primaryHeapEnd(); - for ( ; it != heapEnd; ++it) - counts->add(typeName(*it)); - - return counts; -} - -bool Heap::isBusy() -{ - return m_heap.operationInProgress != NoOperation; -} - -void Heap::reset() -{ - ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable()); - JAVASCRIPTCORE_GC_BEGIN(); - - markRoots(); - - JAVASCRIPTCORE_GC_MARKED(); - - m_heap.nextCell = 0; - m_heap.nextBlock = 0; - m_heap.nextNumber = 0; - m_heap.extraCost = 0; -#if ENABLE(JSC_ZOMBIES) - sweep(); -#endif - resizeBlocks(); - - JAVASCRIPTCORE_GC_END(); - - (*m_activityCallback)(); -} - -void Heap::collectAllGarbage() -{ - ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable()); - JAVASCRIPTCORE_GC_BEGIN(); - - // If the last iteration through the heap deallocated blocks, we need - // to clean up remaining garbage before marking. Otherwise, the conservative - // marking mechanism might follow a pointer to unmapped memory. - if (m_heap.didShrink) - sweep(); - - markRoots(); - - JAVASCRIPTCORE_GC_MARKED(); - - m_heap.nextCell = 0; - m_heap.nextBlock = 0; - m_heap.nextNumber = 0; - m_heap.extraCost = 0; - sweep(); - resizeBlocks(); - - JAVASCRIPTCORE_GC_END(); -} - -LiveObjectIterator Heap::primaryHeapBegin() -{ - return LiveObjectIterator(m_heap, 0); -} - -LiveObjectIterator Heap::primaryHeapEnd() -{ - return LiveObjectIterator(m_heap, m_heap.usedBlocks); -} - -void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback) -{ - m_activityCallback = activityCallback; -} - -GCActivityCallback* Heap::activityCallback() -{ - return m_activityCallback.get(); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h deleted file mode 100644 index a4e2fe1..0000000 --- a/JavaScriptCore/runtime/Collector.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef Collector_h -#define Collector_h - -#include "GCHandle.h" -#include "JSValue.h" -#include <stddef.h> -#include <string.h> -#include <wtf/Bitmap.h> -#include <wtf/FixedArray.h> -#include <wtf/HashCountedSet.h> -#include <wtf/HashSet.h> -#include <wtf/Noncopyable.h> -#include <wtf/OwnPtr.h> -#include <wtf/PageAllocation.h> -#include <wtf/PageAllocationAligned.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/StdLibExtras.h> -#include <wtf/Threading.h> - -#if ENABLE(JSC_MULTIPLE_THREADS) -#include <pthread.h> -#endif - -#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell) - -namespace JSC { - - class CollectorBlock; - class GCActivityCallback; - class JSCell; - class JSGlobalData; - class JSValue; - class MarkedArgumentBuffer; - class MarkStack; - - enum OperationInProgress { NoOperation, Allocation, Collection }; - - class LiveObjectIterator; - -#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP) - const size_t BLOCK_SIZE = 64 * 1024; // 64k -#else - const size_t BLOCK_SIZE = 256 * 1024; // 256k -#endif - - struct CollectorHeap { - size_t nextBlock; - size_t nextCell; - PageAllocationAligned* blocks; - - void* nextNumber; - - size_t numBlocks; - size_t usedBlocks; - - size_t extraCost; - bool didShrink; - - OperationInProgress operationInProgress; - - CollectorBlock* collectorBlock(size_t index) const - { - return static_cast<CollectorBlock*>(blocks[index].base()); - } - }; - - class Heap : public Noncopyable { - public: - class Thread; - - void destroy(); - - void* allocateNumber(size_t); - void* allocate(size_t); - - bool isBusy(); // true if an allocation or collection is in progress - void collectAllGarbage(); - - GCActivityCallback* activityCallback(); - void setActivityCallback(PassOwnPtr<GCActivityCallback>); - - static const size_t minExtraCost = 256; - static const size_t maxExtraCost = 1024 * 1024; - - void reportExtraMemoryCost(size_t cost); - - size_t objectCount() const; - struct Statistics { - size_t size; - size_t free; - }; - Statistics statistics() const; - size_t size() const; - - void protect(JSValue); - // Returns true if the value is no longer protected by any protect pointers - // (though it may still be alive due to heap/stack references). - bool unprotect(JSValue); - - static Heap* heap(JSValue); // 0 for immediate values - static Heap* heap(JSCell*); - - size_t globalObjectCount(); - size_t protectedObjectCount(); - size_t protectedGlobalObjectCount(); - HashCountedSet<const char*>* protectedObjectTypeCounts(); - HashCountedSet<const char*>* objectTypeCounts(); - - void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads. - - static bool isCellMarked(const JSCell*); - static bool checkMarkCell(const JSCell*); - static void markCell(JSCell*); - - WeakGCHandle* addWeakGCHandle(JSCell*); - - void markConservatively(MarkStack&, void* start, void* end); - - void pushTempSortVector(WTF::Vector<ValueStringPair>*); - void popTempSortVector(WTF::Vector<ValueStringPair>*); - - HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; } - - JSGlobalData* globalData() const { return m_globalData; } - static bool isNumber(JSCell*); - - LiveObjectIterator primaryHeapBegin(); - LiveObjectIterator primaryHeapEnd(); - - private: - void reset(); - void sweep(); - static CollectorBlock* cellBlock(const JSCell*); - static size_t cellOffset(const JSCell*); - - friend class JSGlobalData; - Heap(JSGlobalData*); - ~Heap(); - - NEVER_INLINE CollectorBlock* allocateBlock(); - NEVER_INLINE void freeBlock(size_t); - void freeBlocks(); - void resizeBlocks(); - void growBlocks(size_t neededBlocks); - void shrinkBlocks(size_t neededBlocks); - void clearMarkBits(); - void clearMarkBits(CollectorBlock*); - size_t markedCells(size_t startBlock = 0, size_t startCell = 0) const; - - void recordExtraCost(size_t); - - void addToStatistics(Statistics&) const; - - void markRoots(); - void markProtectedObjects(MarkStack&); - void markTempSortVectors(MarkStack&); - void markCurrentThreadConservatively(MarkStack&); - void markCurrentThreadConservativelyInternal(MarkStack&); - void markOtherThreadConservatively(MarkStack&, Thread*); - void markStackObjectsConservatively(MarkStack&); - - void updateWeakGCHandles(); - WeakGCHandlePool* weakGCHandlePool(size_t index); - - typedef HashCountedSet<JSCell*> ProtectCountSet; - - CollectorHeap m_heap; - - ProtectCountSet m_protectedValues; - WTF::Vector<PageAllocationAligned> m_weakGCHandlePools; - WTF::Vector<WTF::Vector<ValueStringPair>* > m_tempSortingVectors; - - HashSet<MarkedArgumentBuffer*>* m_markListSet; - - OwnPtr<GCActivityCallback> m_activityCallback; - -#if ENABLE(JSC_MULTIPLE_THREADS) - void makeUsableFromMultipleThreads(); - - static void unregisterThread(void*); - void unregisterThread(); - - Mutex m_registeredThreadsMutex; - Thread* m_registeredThreads; - pthread_key_t m_currentThreadRegistrar; -#endif - - JSGlobalData* m_globalData; - }; - - // tunable parameters - // derived constants - const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1; - const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK; - const size_t MINIMUM_CELL_SIZE = 64; - const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0); - const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double); - const size_t SMALL_CELL_SIZE = CELL_SIZE / 2; - const size_t CELL_MASK = CELL_SIZE - 1; - const size_t CELL_ALIGN_MASK = ~CELL_MASK; - const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE; // one bitmap byte can represent 8 cells. - - const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8; - const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t); - - struct CollectorBitmap { - FixedArray<uint32_t, BITMAP_WORDS> bits; - bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); } - void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); } - bool getset(size_t n) - { - unsigned i = (1 << (n & 0x1F)); - uint32_t& b = bits[n >> 5]; - bool r = !!(b & i); - b |= i; - return r; - } - void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); } - void clearAll() { memset(bits.data(), 0, sizeof(bits)); } - ALWAYS_INLINE void advanceToNextPossibleFreeCell(size_t& startCell) - { - if (!~bits[startCell >> 5]) - startCell = (startCell & (~0x1F)) + 32; - else - ++startCell; - } - size_t count(size_t startCell = 0) - { - size_t result = 0; - for ( ; (startCell & 0x1F) != 0; ++startCell) { - if (get(startCell)) - ++result; - } - for (size_t i = startCell >> 5; i < BITMAP_WORDS; ++i) - result += WTF::bitCount(bits[i]); - return result; - } - size_t isEmpty() // Much more efficient than testing count() == 0. - { - for (size_t i = 0; i < BITMAP_WORDS; ++i) - if (bits[i] != 0) - return false; - return true; - } - }; - - struct CollectorCell { - FixedArray<double, CELL_ARRAY_LENGTH> memory; - }; - - class CollectorBlock { - public: - FixedArray<CollectorCell, CELLS_PER_BLOCK> cells; - CollectorBitmap marked; - Heap* heap; - }; - - struct HeapConstants { - static const size_t cellSize = CELL_SIZE; - static const size_t cellsPerBlock = CELLS_PER_BLOCK; - typedef CollectorCell Cell; - typedef CollectorBlock Block; - }; - - inline CollectorBlock* Heap::cellBlock(const JSCell* cell) - { - return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK); - } - - inline size_t Heap::cellOffset(const JSCell* cell) - { - return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE; - } - - inline bool Heap::isCellMarked(const JSCell* cell) - { - return cellBlock(cell)->marked.get(cellOffset(cell)); - } - - inline bool Heap::checkMarkCell(const JSCell* cell) - { - return cellBlock(cell)->marked.getset(cellOffset(cell)); - } - - inline void Heap::markCell(JSCell* cell) - { - cellBlock(cell)->marked.set(cellOffset(cell)); - } - - inline void Heap::reportExtraMemoryCost(size_t cost) - { - if (cost > minExtraCost) - recordExtraCost(cost); - } - - inline void* Heap::allocateNumber(size_t s) - { - if (void* result = m_heap.nextNumber) { - m_heap.nextNumber = 0; - return result; - } - - void* result = allocate(s); - m_heap.nextNumber = static_cast<char*>(result) + (CELL_SIZE / 2); - return result; - } - - - inline WeakGCHandlePool* Heap::weakGCHandlePool(size_t index) - { - return static_cast<WeakGCHandlePool*>(m_weakGCHandlePools[index].base()); - } -} // namespace JSC - -#endif /* Collector_h */ diff --git a/JavaScriptCore/runtime/CollectorHeapIterator.h b/JavaScriptCore/runtime/CollectorHeapIterator.h deleted file mode 100644 index 9d107b7..0000000 --- a/JavaScriptCore/runtime/CollectorHeapIterator.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Collector.h" - -#ifndef CollectorHeapIterator_h -#define CollectorHeapIterator_h - -namespace JSC { - - class CollectorHeapIterator { - public: - bool operator!=(const CollectorHeapIterator& other); - JSCell* operator*() const; - - protected: - CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell); - void advance(size_t max); - - CollectorHeap& m_heap; - size_t m_block; - size_t m_cell; - }; - - class LiveObjectIterator : public CollectorHeapIterator { - public: - LiveObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0); - LiveObjectIterator& operator++(); - }; - - class DeadObjectIterator : public CollectorHeapIterator { - public: - DeadObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0); - DeadObjectIterator& operator++(); - }; - - class ObjectIterator : public CollectorHeapIterator { - public: - ObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0); - ObjectIterator& operator++(); - }; - - inline CollectorHeapIterator::CollectorHeapIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) - : m_heap(heap) - , m_block(startBlock) - , m_cell(startCell) - { - } - - inline bool CollectorHeapIterator::operator!=(const CollectorHeapIterator& other) - { - return m_block != other.m_block || m_cell != other.m_cell; - } - - inline JSCell* CollectorHeapIterator::operator*() const - { - return reinterpret_cast<JSCell*>(&m_heap.collectorBlock(m_block)->cells[m_cell]); - } - - // Iterators advance up to the next-to-last -- and not the last -- cell in a - // block, since the last cell is a dummy sentinel. - inline void CollectorHeapIterator::advance(size_t max) - { - ++m_cell; - if (m_cell == max) { - m_cell = 0; - ++m_block; - } - } - - inline LiveObjectIterator::LiveObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) - : CollectorHeapIterator(heap, startBlock, startCell - 1) - { - ++(*this); - } - - inline LiveObjectIterator& LiveObjectIterator::operator++() - { - advance(HeapConstants::cellsPerBlock - 1); - if (m_block < m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell < m_heap.nextCell)) - return *this; - - while (m_block < m_heap.usedBlocks && !m_heap.collectorBlock(m_block)->marked.get(m_cell)) - advance(HeapConstants::cellsPerBlock - 1); - return *this; - } - - inline DeadObjectIterator::DeadObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) - : CollectorHeapIterator(heap, startBlock, startCell - 1) - { - ++(*this); - } - - inline DeadObjectIterator& DeadObjectIterator::operator++() - { - do { - advance(HeapConstants::cellsPerBlock - 1); - ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell)); - } while (m_block < m_heap.usedBlocks && m_heap.collectorBlock(m_block)->marked.get(m_cell)); - return *this; - } - - inline ObjectIterator::ObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) - : CollectorHeapIterator(heap, startBlock, startCell - 1) - { - ++(*this); - } - - inline ObjectIterator& ObjectIterator::operator++() - { - advance(HeapConstants::cellsPerBlock - 1); - return *this; - } - -} // namespace JSC - -#endif // CollectorHeapIterator_h diff --git a/JavaScriptCore/runtime/CommonIdentifiers.cpp b/JavaScriptCore/runtime/CommonIdentifiers.cpp deleted file mode 100644 index 1561102..0000000 --- a/JavaScriptCore/runtime/CommonIdentifiers.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "CommonIdentifiers.h" - -namespace JSC { - -static const char* const nullCString = 0; - -#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name) - -CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData) - : nullIdentifier(globalData, nullCString) - , emptyIdentifier(globalData, "") - , underscoreProto(globalData, "__proto__") - , thisIdentifier(globalData, "this") - , useStrictIdentifier(globalData, "use strict") - JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME) -{ -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h deleted file mode 100644 index 1e22b6a..0000000 --- a/JavaScriptCore/runtime/CommonIdentifiers.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef CommonIdentifiers_h -#define CommonIdentifiers_h - -#include "Identifier.h" -#include <wtf/Noncopyable.h> - -// MarkedArgumentBuffer of property names, passed to a macro so we can do set them up various -// ways without repeating the list. -#define JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \ - macro(__defineGetter__) \ - macro(__defineSetter__) \ - macro(__lookupGetter__) \ - macro(__lookupSetter__) \ - macro(apply) \ - macro(arguments) \ - macro(call) \ - macro(callee) \ - macro(caller) \ - macro(compile) \ - macro(configurable) \ - macro(constructor) \ - macro(create) \ - macro(defineProperty) \ - macro(defineProperties) \ - macro(enumerable) \ - macro(eval) \ - macro(exec) \ - macro(fromCharCode) \ - macro(global) \ - macro(get) \ - macro(getPrototypeOf) \ - macro(getOwnPropertyDescriptor) \ - macro(getOwnPropertyNames) \ - macro(hasOwnProperty) \ - macro(ignoreCase) \ - macro(index) \ - macro(input) \ - macro(isArray) \ - macro(isPrototypeOf) \ - macro(keys) \ - macro(length) \ - macro(message) \ - macro(multiline) \ - macro(name) \ - macro(now) \ - macro(parse) \ - macro(propertyIsEnumerable) \ - macro(prototype) \ - macro(set) \ - macro(source) \ - macro(test) \ - macro(toExponential) \ - macro(toFixed) \ - macro(toISOString) \ - macro(toJSON) \ - macro(toLocaleString) \ - macro(toPrecision) \ - macro(toString) \ - macro(UTC) \ - macro(value) \ - macro(valueOf) \ - macro(writable) \ - macro(displayName) - -namespace JSC { - - class CommonIdentifiers : public Noncopyable { - private: - CommonIdentifiers(JSGlobalData*); - friend class JSGlobalData; - - public: - const Identifier nullIdentifier; - const Identifier emptyIdentifier; - const Identifier underscoreProto; - const Identifier thisIdentifier; - const Identifier useStrictIdentifier; - -#define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name; - JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL) -#undef JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL - }; - -} // namespace JSC - -#endif // CommonIdentifiers_h diff --git a/JavaScriptCore/runtime/Completion.cpp b/JavaScriptCore/runtime/Completion.cpp deleted file mode 100644 index eeb8b0d..0000000 --- a/JavaScriptCore/runtime/Completion.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2007 Apple Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "Completion.h" - -#include "CallFrame.h" -#include "JSGlobalObject.h" -#include "JSLock.h" -#include "Interpreter.h" -#include "Parser.h" -#include "Debugger.h" -#include "WTFThreadData.h" -#include <stdio.h> - -namespace JSC { - -Completion checkSyntax(ExecState* exec, const SourceCode& source) -{ - JSLock lock(exec); - ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable()); - - RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source); - JSObject* error = program->checkSyntax(exec); - if (error) - return Completion(Throw, error); - - return Completion(Normal); -} - -Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue) -{ - JSLock lock(exec); - ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable()); - - RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source); - JSObject* error = program->compile(exec, scopeChain.node()); - if (error) - return Completion(Throw, error); - - JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec); - - JSValue result = exec->interpreter()->execute(program.get(), exec, scopeChain.node(), thisObj); - - if (exec->hadException()) { - JSValue exception = exec->exception(); - exec->clearException(); - - ComplType exceptionType = Throw; - if (exception.isObject()) - exceptionType = asObject(exception)->exceptionType(); - return Completion(exceptionType, exception); - } - return Completion(Normal, result); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Completion.h b/JavaScriptCore/runtime/Completion.h deleted file mode 100644 index 63b315e..0000000 --- a/JavaScriptCore/runtime/Completion.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2007 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Completion_h -#define Completion_h - -#include "JSValue.h" - -namespace JSC { - - class ExecState; - class ScopeChain; - class SourceCode; - - enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted, Terminated }; - - /* - * Completion objects are used to convey the return status and value - * from functions. - */ - class Completion { - public: - Completion(ComplType type = Normal, JSValue value = JSValue()) - : m_type(type) - , m_value(value) - { - } - - ComplType complType() const { return m_type; } - JSValue value() const { return m_value; } - void setValue(JSValue v) { m_value = v; } - bool isValueCompletion() const { return m_value; } - - private: - ComplType m_type; - JSValue m_value; - }; - - Completion checkSyntax(ExecState*, const SourceCode&); - Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValue thisValue = JSValue()); - -} // namespace JSC - -#endif // Completion_h diff --git a/JavaScriptCore/runtime/ConstructData.cpp b/JavaScriptCore/runtime/ConstructData.cpp deleted file mode 100644 index 5da2a91..0000000 --- a/JavaScriptCore/runtime/ConstructData.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ConstructData.h" - -#include "Executable.h" -#include "Interpreter.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" - -namespace JSC { - -JSObject* construct(ExecState* exec, JSValue constructorObject, ConstructType constructType, const ConstructData& constructData, const ArgList& args) -{ - ASSERT(constructType == ConstructTypeJS || constructType == ConstructTypeHost); - return exec->interpreter()->executeConstruct(exec, asObject(constructorObject), constructType, constructData, args); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ConstructData.h b/JavaScriptCore/runtime/ConstructData.h deleted file mode 100644 index 3d5f732..0000000 --- a/JavaScriptCore/runtime/ConstructData.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ConstructData_h -#define ConstructData_h - -#include "JSValue.h" - -namespace JSC { - - class ArgList; - class ExecState; - class FunctionExecutable; - class JSObject; - class ScopeChainNode; - - enum ConstructType { - ConstructTypeNone, - ConstructTypeHost, - ConstructTypeJS - }; - - typedef EncodedJSValue (JSC_HOST_CALL *NativeConstructor)(ExecState*); - - union ConstructData { - struct { - NativeConstructor function; - } native; - struct { - FunctionExecutable* functionExecutable; - ScopeChainNode* scopeChain; - } js; - }; - - JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&); - -} // namespace JSC - -#endif // ConstructData_h diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp deleted file mode 100644 index dcbe12d..0000000 --- a/JavaScriptCore/runtime/DateConstructor.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "DateConstructor.h" - -#include "DateConversion.h" -#include "DateInstance.h" -#include "DatePrototype.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "ObjectPrototype.h" -#include "PrototypeFunction.h" -#include <math.h> -#include <time.h> -#include <wtf/DateMath.h> -#include <wtf/MathExtras.h> - -#if OS(WINCE) && !PLATFORM(QT) -extern "C" time_t time(time_t* timer); // Provided by libce. -#endif - -#if HAVE(SYS_TIME_H) -#include <sys/time.h> -#endif - -#if HAVE(SYS_TIMEB_H) -#include <sys/timeb.h> -#endif - -using namespace WTF; - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(DateConstructor); - -static EncodedJSValue JSC_HOST_CALL dateParse(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState*); - -DateConstructor::DateConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, datePrototype->classInfo()->className)) -{ - putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly); - - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum); - - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(7), ReadOnly | DontEnum | DontDelete); -} - -// ECMA 15.9.3 -JSObject* constructDate(ExecState* exec, const ArgList& args) -{ - int numArgs = args.size(); - - double value; - - if (numArgs == 0) // new Date() ECMA 15.9.3.3 - value = jsCurrentTime(); - else if (numArgs == 1) { - if (args.at(0).inherits(&DateInstance::info)) - value = asDateInstance(args.at(0))->internalNumber(); - else { - JSValue primitive = args.at(0).toPrimitive(exec); - if (primitive.isString()) - value = parseDate(exec, primitive.getString(exec)); - else - value = primitive.toNumber(exec); - } - } else { - double doubleArguments[7] = { - args.at(0).toNumber(exec), - args.at(1).toNumber(exec), - args.at(2).toNumber(exec), - args.at(3).toNumber(exec), - args.at(4).toNumber(exec), - args.at(5).toNumber(exec), - args.at(6).toNumber(exec) - }; - if (isnan(doubleArguments[0]) - || isnan(doubleArguments[1]) - || (numArgs >= 3 && isnan(doubleArguments[2])) - || (numArgs >= 4 && isnan(doubleArguments[3])) - || (numArgs >= 5 && isnan(doubleArguments[4])) - || (numArgs >= 6 && isnan(doubleArguments[5])) - || (numArgs >= 7 && isnan(doubleArguments[6]))) - value = NaN; - else { - GregorianDateTime t; - int year = JSC::toInt32(doubleArguments[0]); - t.year = (year >= 0 && year <= 99) ? year : year - 1900; - t.month = JSC::toInt32(doubleArguments[1]); - t.monthDay = (numArgs >= 3) ? JSC::toInt32(doubleArguments[2]) : 1; - t.hour = JSC::toInt32(doubleArguments[3]); - t.minute = JSC::toInt32(doubleArguments[4]); - t.second = JSC::toInt32(doubleArguments[5]); - t.isDST = -1; - double ms = (numArgs >= 7) ? doubleArguments[6] : 0; - value = gregorianDateTimeToMS(exec, t, ms, false); - } - } - - return new (exec) DateInstance(exec, value); -} - -static EncodedJSValue JSC_HOST_CALL constructWithDateConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructDate(exec, args)); -} - -ConstructType DateConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithDateConstructor; - return ConstructTypeHost; -} - -// ECMA 15.9.2 -static EncodedJSValue JSC_HOST_CALL callDate(ExecState* exec) -{ - time_t localTime = time(0); - tm localTM; - getLocalTime(&localTime, &localTM); - GregorianDateTime ts(exec, localTM); - DateConversionBuffer date; - DateConversionBuffer time; - formatDate(ts, date); - formatTime(ts, time); - return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time)); -} - -CallType DateConstructor::getCallData(CallData& callData) -{ - callData.native.function = callDate; - return CallTypeHost; -} - -static EncodedJSValue JSC_HOST_CALL dateParse(ExecState* exec) -{ - return JSValue::encode(jsNumber(parseDate(exec, exec->argument(0).toString(exec)))); -} - -static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*) -{ - return JSValue::encode(jsNumber(jsCurrentTime())); -} - -static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec) -{ - double doubleArguments[7] = { - exec->argument(0).toNumber(exec), - exec->argument(1).toNumber(exec), - exec->argument(2).toNumber(exec), - exec->argument(3).toNumber(exec), - exec->argument(4).toNumber(exec), - exec->argument(5).toNumber(exec), - exec->argument(6).toNumber(exec) - }; - int n = exec->argumentCount(); - if (isnan(doubleArguments[0]) - || isnan(doubleArguments[1]) - || (n >= 3 && isnan(doubleArguments[2])) - || (n >= 4 && isnan(doubleArguments[3])) - || (n >= 5 && isnan(doubleArguments[4])) - || (n >= 6 && isnan(doubleArguments[5])) - || (n >= 7 && isnan(doubleArguments[6]))) - return JSValue::encode(jsNaN()); - - GregorianDateTime t; - int year = JSC::toInt32(doubleArguments[0]); - t.year = (year >= 0 && year <= 99) ? year : year - 1900; - t.month = JSC::toInt32(doubleArguments[1]); - t.monthDay = (n >= 3) ? JSC::toInt32(doubleArguments[2]) : 1; - t.hour = JSC::toInt32(doubleArguments[3]); - t.minute = JSC::toInt32(doubleArguments[4]); - t.second = JSC::toInt32(doubleArguments[5]); - double ms = (n >= 7) ? doubleArguments[6] : 0; - return JSValue::encode(jsNumber(timeClip(gregorianDateTimeToMS(exec, t, ms, true)))); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/DateConstructor.h b/JavaScriptCore/runtime/DateConstructor.h deleted file mode 100644 index c8ca456..0000000 --- a/JavaScriptCore/runtime/DateConstructor.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef DateConstructor_h -#define DateConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class DatePrototype; - - class DateConstructor : public InternalFunction { - public: - DateConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure, DatePrototype*); - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - - JSObject* constructDate(ExecState*, const ArgList&); - -} // namespace JSC - -#endif // DateConstructor_h diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp deleted file mode 100644 index d4b8232..0000000 --- a/JavaScriptCore/runtime/DateConversion.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Alternatively, the contents of this file may be used under the terms - * of either the Mozilla Public License Version 1.1, found at - * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public - * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html - * (the "GPL"), in which case the provisions of the MPL or the GPL are - * applicable instead of those above. If you wish to allow use of your - * version of this file only under the terms of one of those two - * licenses (the MPL or the GPL) and not to allow others to use your - * version of this file under the LGPL, indicate your decision by - * deletingthe provisions above and replace them with the notice and - * other provisions required by the MPL or the GPL, as the case may be. - * If you do not delete the provisions above, a recipient may use your - * version of this file under any of the LGPL, the MPL or the GPL. - */ - -#include "config.h" -#include "DateConversion.h" - -#include "CallFrame.h" -#include "UString.h" -#include <wtf/DateMath.h> -#include <wtf/StringExtras.h> -#include <wtf/text/CString.h> - -using namespace WTF; - -namespace JSC { - -double parseDate(ExecState* exec, const UString &date) -{ - if (date == exec->globalData().cachedDateString) - return exec->globalData().cachedDateStringValue; - double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data()); - if (isnan(value)) - value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data()); - exec->globalData().cachedDateString = date; - exec->globalData().cachedDateStringValue = value; - return value; -} - -void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer) -{ - snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d", - weekdayName[(t.weekDay + 6) % 7], - monthName[t.month], t.monthDay, t.year + 1900); -} - -void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer) -{ - snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d", - weekdayName[(t.weekDay + 6) % 7], - t.monthDay, monthName[t.month], t.year + 1900); -} - -void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer) -{ - int offset = abs(gmtoffset(t)); - char timeZoneName[70]; - struct tm gtm = t; - strftime(timeZoneName, sizeof(timeZoneName), "%Z", >m); - - if (timeZoneName[0]) { - snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)", - t.hour, t.minute, t.second, - gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName); - } else { - snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d", - t.hour, t.minute, t.second, - gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60); - } -} - -void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer) -{ - snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/DateConversion.h b/JavaScriptCore/runtime/DateConversion.h deleted file mode 100644 index ff32b50..0000000 --- a/JavaScriptCore/runtime/DateConversion.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - */ - -#ifndef DateConversion_h -#define DateConversion_h - -#include "UString.h" - -namespace JSC { - -class ExecState; -struct GregorianDateTime; - -static const unsigned DateConversionBufferSize = 100; -typedef char DateConversionBuffer[DateConversionBufferSize]; - -double parseDate(ExecState* exec, const UString&); -void formatDate(const GregorianDateTime&, DateConversionBuffer&); -void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&); -void formatTime(const GregorianDateTime&, DateConversionBuffer&); -void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&); - -} // namespace JSC - -#endif // DateConversion_h diff --git a/JavaScriptCore/runtime/DateInstance.cpp b/JavaScriptCore/runtime/DateInstance.cpp deleted file mode 100644 index 8562e2d..0000000 --- a/JavaScriptCore/runtime/DateInstance.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "DateInstance.h" - -#include "JSGlobalObject.h" - -#include <math.h> -#include <wtf/DateMath.h> -#include <wtf/MathExtras.h> - -using namespace WTF; - -namespace JSC { - -const ClassInfo DateInstance::info = {"Date", 0, 0, 0}; - -DateInstance::DateInstance(ExecState*, NonNullPassRefPtr<Structure> structure) - : JSWrapperObject(structure) -{ - setInternalValue(jsNaN()); -} - -DateInstance::DateInstance(ExecState*, NonNullPassRefPtr<Structure> structure, double time) - : JSWrapperObject(structure) -{ - setInternalValue(jsNumber(timeClip(time))); -} - -DateInstance::DateInstance(ExecState* exec, double time) - : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure()) -{ - setInternalValue(jsNumber(timeClip(time))); -} - -const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exec) const -{ - double milli = internalNumber(); - if (isnan(milli)) - return 0; - - if (!m_data) - m_data = exec->globalData().dateInstanceCache.add(milli); - - if (m_data->m_gregorianDateTimeCachedForMS != milli) { - msToGregorianDateTime(exec, milli, false, m_data->m_cachedGregorianDateTime); - m_data->m_gregorianDateTimeCachedForMS = milli; - } - return &m_data->m_cachedGregorianDateTime; -} - -const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(ExecState* exec) const -{ - double milli = internalNumber(); - if (isnan(milli)) - return 0; - - if (!m_data) - m_data = exec->globalData().dateInstanceCache.add(milli); - - if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) { - msToGregorianDateTime(exec, milli, true, m_data->m_cachedGregorianDateTimeUTC); - m_data->m_gregorianDateTimeUTCCachedForMS = milli; - } - return &m_data->m_cachedGregorianDateTimeUTC; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/DateInstance.h b/JavaScriptCore/runtime/DateInstance.h deleted file mode 100644 index 77d46de..0000000 --- a/JavaScriptCore/runtime/DateInstance.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef DateInstance_h -#define DateInstance_h - -#include "JSWrapperObject.h" - -namespace WTF { - struct GregorianDateTime; -} - -namespace JSC { - - class DateInstance : public JSWrapperObject { - public: - DateInstance(ExecState*, double); - DateInstance(ExecState*, NonNullPassRefPtr<Structure>, double); - explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>); - - double internalNumber() const { return internalValue().uncheckedGetNumber(); } - - static JS_EXPORTDATA const ClassInfo info; - - const GregorianDateTime* gregorianDateTime(ExecState* exec) const - { - if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber()) - return &m_data->m_cachedGregorianDateTime; - return calculateGregorianDateTime(exec); - } - - const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const - { - if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber()) - return &m_data->m_cachedGregorianDateTimeUTC; - return calculateGregorianDateTimeUTC(exec); - } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags; - - private: - const GregorianDateTime* calculateGregorianDateTime(ExecState*) const; - const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const; - virtual const ClassInfo* classInfo() const { return &info; } - - mutable RefPtr<DateInstanceData> m_data; - }; - - DateInstance* asDateInstance(JSValue); - - inline DateInstance* asDateInstance(JSValue value) - { - ASSERT(asObject(value)->inherits(&DateInstance::info)); - return static_cast<DateInstance*>(asObject(value)); - } - -} // namespace JSC - -#endif // DateInstance_h diff --git a/JavaScriptCore/runtime/DateInstanceCache.h b/JavaScriptCore/runtime/DateInstanceCache.h deleted file mode 100644 index b60c29a..0000000 --- a/JavaScriptCore/runtime/DateInstanceCache.h +++ /dev/null @@ -1,94 +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 DateInstanceCache_h -#define DateInstanceCache_h - -#include <wtf/DateMath.h> -#include <wtf/HashFunctions.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> - -namespace JSC { - - extern const double NaN; - - class DateInstanceData : public RefCounted<DateInstanceData> { - public: - static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); } - - double m_gregorianDateTimeCachedForMS; - GregorianDateTime m_cachedGregorianDateTime; - double m_gregorianDateTimeUTCCachedForMS; - GregorianDateTime m_cachedGregorianDateTimeUTC; - - private: - DateInstanceData() - : m_gregorianDateTimeCachedForMS(NaN) - , m_gregorianDateTimeUTCCachedForMS(NaN) - { - } - }; - - class DateInstanceCache { - public: - DateInstanceCache() - { - reset(); - } - - void reset() - { - for (size_t i = 0; i < cacheSize; ++i) - m_cache[i].key = NaN; - } - - DateInstanceData* add(double d) - { - CacheEntry& entry = lookup(d); - if (d == entry.key) - return entry.value.get(); - - entry.key = d; - entry.value = DateInstanceData::create(); - return entry.value.get(); - } - - private: - static const size_t cacheSize = 16; - - struct CacheEntry { - double key; - RefPtr<DateInstanceData> value; - }; - - CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } - - FixedArray<CacheEntry, cacheSize> m_cache; - }; - -} // namespace JSC - -#endif // DateInstanceCache_h diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp deleted file mode 100644 index 085cb33..0000000 --- a/JavaScriptCore/runtime/DatePrototype.cpp +++ /dev/null @@ -1,1094 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008, 2009 Torch Mobile, Inc. All rights reserved. - * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "DatePrototype.h" - -#include "DateConversion.h" -#include "DateInstance.h" -#include "Error.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "Lookup.h" -#include "ObjectPrototype.h" - -#if !PLATFORM(MAC) && HAVE(LANGINFO_H) -#include <langinfo.h> -#endif - -#include <limits.h> -#include <locale.h> -#include <math.h> -#include <stdlib.h> -#include <time.h> -#include <wtf/Assertions.h> -#include <wtf/DateMath.h> -#include <wtf/MathExtras.h> -#include <wtf/StringExtras.h> -#include <wtf/UnusedParam.h> - -#if HAVE(SYS_PARAM_H) -#include <sys/param.h> -#endif - -#if HAVE(SYS_TIME_H) -#include <sys/time.h> -#endif - -#if HAVE(SYS_TIMEB_H) -#include <sys/timeb.h> -#endif - -#if PLATFORM(MAC) -#include <CoreFoundation/CoreFoundation.h> -#endif - -#if OS(WINCE) && !PLATFORM(QT) -extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); //provided by libce -#endif - -using namespace WTF; - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(DatePrototype); - -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState*); -static EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState*); - -} - -#include "DatePrototype.lut.h" - -namespace JSC { - -enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime }; - -#if PLATFORM(MAC) - -// FIXME: Since this is superior to the strftime-based version, why limit this to PLATFORM(MAC)? -// Instead we should consider using this whenever PLATFORM(CF) is true. - -static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateFormatterStyle defaultStyle) -{ - if (string == "short") - return kCFDateFormatterShortStyle; - if (string == "medium") - return kCFDateFormatterMediumStyle; - if (string == "long") - return kCFDateFormatterLongStyle; - if (string == "full") - return kCFDateFormatterFullStyle; - return defaultStyle; -} - -static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMilliseconds, LocaleDateTimeFormat format) -{ - CFDateFormatterStyle dateStyle = (format != LocaleTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle); - CFDateFormatterStyle timeStyle = (format != LocaleDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle); - - bool useCustomFormat = false; - UString customFormatString; - - UString arg0String = exec->argument(0).toString(exec); - if (arg0String == "custom" && !exec->argument(1).isUndefined()) { - useCustomFormat = true; - customFormatString = exec->argument(1).toString(exec); - } else if (format == LocaleDateAndTime && !exec->argument(1).isUndefined()) { - dateStyle = styleFromArgString(arg0String, dateStyle); - timeStyle = styleFromArgString(exec->argument(1).toString(exec), timeStyle); - } else if (format != LocaleTime && !exec->argument(0).isUndefined()) - dateStyle = styleFromArgString(arg0String, dateStyle); - else if (format != LocaleDate && !exec->argument(0).isUndefined()) - timeStyle = styleFromArgString(arg0String, timeStyle); - - CFLocaleRef locale = CFLocaleCopyCurrent(); - CFDateFormatterRef formatter = CFDateFormatterCreate(0, locale, dateStyle, timeStyle); - CFRelease(locale); - - if (useCustomFormat) { - CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, customFormatString.characters(), customFormatString.length()); - CFDateFormatterSetFormat(formatter, customFormatCFString); - CFRelease(customFormatCFString); - } - - CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, floor(timeInMilliseconds / msPerSecond) - kCFAbsoluteTimeIntervalSince1970); - - CFRelease(formatter); - - // We truncate the string returned from CFDateFormatter if it's absurdly long (> 200 characters). - // That's not great error handling, but it just won't happen so it doesn't matter. - UChar buffer[200]; - const size_t bufferLength = WTF_ARRAY_LENGTH(buffer); - size_t length = CFStringGetLength(string); - ASSERT(length <= bufferLength); - if (length > bufferLength) - length = bufferLength; - CFStringGetCharacters(string, CFRangeMake(0, length), buffer); - - CFRelease(string); - - return jsNontrivialString(exec, UString(buffer, length)); -} - -#else // !PLATFORM(MAC) - -static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format) -{ -#if HAVE(LANGINFO_H) - static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT }; -#elif (OS(WINCE) && !PLATFORM(QT)) || OS(SYMBIAN) - // strftime() does not support '#' on WinCE or Symbian - static const char* const formatStrings[] = { "%c", "%x", "%X" }; -#else - static const char* const formatStrings[] = { "%#c", "%#x", "%X" }; -#endif - - // Offset year if needed - struct tm localTM = gdt; - int year = gdt.year + 1900; - bool yearNeedsOffset = year < 1900 || year > 2038; - if (yearNeedsOffset) - localTM.tm_year = equivalentYearForDST(year) - 1900; - -#if HAVE(LANGINFO_H) - // We do not allow strftime to generate dates with 2-digits years, - // both to avoid ambiguity, and a crash in strncpy, for years that - // need offset. - char* formatString = strdup(nl_langinfo(formats[format])); - char* yPos = strchr(formatString, 'y'); - if (yPos) - *yPos = 'Y'; -#endif - - // Do the formatting - const int bufsize = 128; - char timebuffer[bufsize]; - -#if HAVE(LANGINFO_H) - size_t ret = strftime(timebuffer, bufsize, formatString, &localTM); - free(formatString); -#else - size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM); -#endif - - if (ret == 0) - return jsEmptyString(exec); - - // Copy original into the buffer - if (yearNeedsOffset && format != LocaleTime) { - static const int yearLen = 5; // FIXME will be a problem in the year 10,000 - char yearString[yearLen]; - - snprintf(yearString, yearLen, "%d", localTM.tm_year + 1900); - char* yearLocation = strstr(timebuffer, yearString); - snprintf(yearString, yearLen, "%d", year); - - strncpy(yearLocation, yearString, yearLen - 1); - } - - // Convert multi-byte result to UNICODE. - // If __STDC_ISO_10646__ is defined, wide character represents - // UTF-16 (or UTF-32) code point. In most modern Unix like system - // (e.g. Linux with glibc 2.2 and above) the macro is defined, - // and wide character represents UTF-32 code point. - // Here we static_cast potential UTF-32 to UTF-16, it should be - // safe because date and (or) time related characters in different languages - // should be in UNICODE BMP. If mbstowcs fails, we just fall - // back on using multi-byte result as-is. -#ifdef __STDC_ISO_10646__ - UChar buffer[bufsize]; - wchar_t tempbuffer[bufsize]; - size_t length = mbstowcs(tempbuffer, timebuffer, bufsize - 1); - if (length != static_cast<size_t>(-1)) { - for (size_t i = 0; i < length; ++i) - buffer[i] = static_cast<UChar>(tempbuffer[i]); - return jsNontrivialString(exec, UString(buffer, length)); - } -#endif - - return jsNontrivialString(exec, timebuffer); -} - -static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double, LocaleDateTimeFormat format) -{ - const GregorianDateTime* gregorianDateTime = dateObject->gregorianDateTime(exec); - if (!gregorianDateTime) - return jsNontrivialString(exec, "Invalid Date"); - return formatLocaleDate(exec, *gregorianDateTime, format); -} - -#endif // !PLATFORM(MAC) - -// Converts a list of arguments sent to a Date member function into milliseconds, updating -// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. -// -// Format of member function: f([hour,] [min,] [sec,] [ms]) -static bool fillStructuresUsingTimeArgs(ExecState* exec, int maxArgs, double* ms, GregorianDateTime* t) -{ - double milliseconds = 0; - bool ok = true; - int idx = 0; - int numArgs = exec->argumentCount(); - - // JS allows extra trailing arguments -- ignore them - if (numArgs > maxArgs) - numArgs = maxArgs; - - // hours - if (maxArgs >= 4 && idx < numArgs) { - t->hour = 0; - double hours = exec->argument(idx++).toIntegerPreserveNaN(exec); - ok = isfinite(hours); - milliseconds += hours * msPerHour; - } - - // minutes - if (maxArgs >= 3 && idx < numArgs && ok) { - t->minute = 0; - double minutes = exec->argument(idx++).toIntegerPreserveNaN(exec); - ok = isfinite(minutes); - milliseconds += minutes * msPerMinute; - } - - // seconds - if (maxArgs >= 2 && idx < numArgs && ok) { - t->second = 0; - double seconds = exec->argument(idx++).toIntegerPreserveNaN(exec); - ok = isfinite(seconds); - milliseconds += seconds * msPerSecond; - } - - if (!ok) - return false; - - // milliseconds - if (idx < numArgs) { - double millis = exec->argument(idx).toIntegerPreserveNaN(exec); - ok = isfinite(millis); - milliseconds += millis; - } else - milliseconds += *ms; - - *ms = milliseconds; - return ok; -} - -// Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating -// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. -// -// Format of member function: f([years,] [months,] [days]) -static bool fillStructuresUsingDateArgs(ExecState *exec, int maxArgs, double *ms, GregorianDateTime *t) -{ - int idx = 0; - bool ok = true; - int numArgs = exec->argumentCount(); - - // JS allows extra trailing arguments -- ignore them - if (numArgs > maxArgs) - numArgs = maxArgs; - - // years - if (maxArgs >= 3 && idx < numArgs) { - double years = exec->argument(idx++).toIntegerPreserveNaN(exec); - ok = isfinite(years); - t->year = toInt32(years - 1900); - } - // months - if (maxArgs >= 2 && idx < numArgs && ok) { - double months = exec->argument(idx++).toIntegerPreserveNaN(exec); - ok = isfinite(months); - t->month = toInt32(months); - } - // days - if (idx < numArgs && ok) { - double days = exec->argument(idx++).toIntegerPreserveNaN(exec); - ok = isfinite(days); - t->monthDay = 0; - *ms += days * msPerDay; - } - - return ok; -} - -const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState::dateTable}; - -/* Source for DatePrototype.lut.h -@begin dateTable - toString dateProtoFuncToString DontEnum|Function 0 - toISOString dateProtoFuncToISOString DontEnum|Function 0 - toUTCString dateProtoFuncToUTCString DontEnum|Function 0 - toDateString dateProtoFuncToDateString DontEnum|Function 0 - toTimeString dateProtoFuncToTimeString DontEnum|Function 0 - toLocaleString dateProtoFuncToLocaleString DontEnum|Function 0 - toLocaleDateString dateProtoFuncToLocaleDateString DontEnum|Function 0 - toLocaleTimeString dateProtoFuncToLocaleTimeString DontEnum|Function 0 - valueOf dateProtoFuncGetTime DontEnum|Function 0 - getTime dateProtoFuncGetTime DontEnum|Function 0 - getFullYear dateProtoFuncGetFullYear DontEnum|Function 0 - getUTCFullYear dateProtoFuncGetUTCFullYear DontEnum|Function 0 - toGMTString dateProtoFuncToGMTString DontEnum|Function 0 - getMonth dateProtoFuncGetMonth DontEnum|Function 0 - getUTCMonth dateProtoFuncGetUTCMonth DontEnum|Function 0 - getDate dateProtoFuncGetDate DontEnum|Function 0 - getUTCDate dateProtoFuncGetUTCDate DontEnum|Function 0 - getDay dateProtoFuncGetDay DontEnum|Function 0 - getUTCDay dateProtoFuncGetUTCDay DontEnum|Function 0 - getHours dateProtoFuncGetHours DontEnum|Function 0 - getUTCHours dateProtoFuncGetUTCHours DontEnum|Function 0 - getMinutes dateProtoFuncGetMinutes DontEnum|Function 0 - getUTCMinutes dateProtoFuncGetUTCMinutes DontEnum|Function 0 - getSeconds dateProtoFuncGetSeconds DontEnum|Function 0 - getUTCSeconds dateProtoFuncGetUTCSeconds DontEnum|Function 0 - getMilliseconds dateProtoFuncGetMilliSeconds DontEnum|Function 0 - getUTCMilliseconds dateProtoFuncGetUTCMilliseconds DontEnum|Function 0 - getTimezoneOffset dateProtoFuncGetTimezoneOffset DontEnum|Function 0 - setTime dateProtoFuncSetTime DontEnum|Function 1 - setMilliseconds dateProtoFuncSetMilliSeconds DontEnum|Function 1 - setUTCMilliseconds dateProtoFuncSetUTCMilliseconds DontEnum|Function 1 - setSeconds dateProtoFuncSetSeconds DontEnum|Function 2 - setUTCSeconds dateProtoFuncSetUTCSeconds DontEnum|Function 2 - setMinutes dateProtoFuncSetMinutes DontEnum|Function 3 - setUTCMinutes dateProtoFuncSetUTCMinutes DontEnum|Function 3 - setHours dateProtoFuncSetHours DontEnum|Function 4 - setUTCHours dateProtoFuncSetUTCHours DontEnum|Function 4 - setDate dateProtoFuncSetDate DontEnum|Function 1 - setUTCDate dateProtoFuncSetUTCDate DontEnum|Function 1 - setMonth dateProtoFuncSetMonth DontEnum|Function 2 - setUTCMonth dateProtoFuncSetUTCMonth DontEnum|Function 2 - setFullYear dateProtoFuncSetFullYear DontEnum|Function 3 - setUTCFullYear dateProtoFuncSetUTCFullYear DontEnum|Function 3 - setYear dateProtoFuncSetYear DontEnum|Function 1 - getYear dateProtoFuncGetYear DontEnum|Function 0 - toJSON dateProtoFuncToJSON DontEnum|Function 1 -@end -*/ - -// ECMA 15.9.4 - -DatePrototype::DatePrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : DateInstance(exec, structure) -{ - // The constructor will be added later, after DateConstructor has been built. - putAnonymousValue(0, globalObject); -} - -bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticFunctionSlot<JSObject>(exec, ExecState::dateTable(exec), this, propertyName, slot); -} - - -bool DatePrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticFunctionDescriptor<JSObject>(exec, ExecState::dateTable(exec), this, propertyName, descriptor); -} - -// Functions - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); - DateConversionBuffer date; - DateConversionBuffer time; - formatDate(*gregorianDateTime, date); - formatTime(*gregorianDateTime, time); - return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); - DateConversionBuffer date; - DateConversionBuffer time; - formatDateUTCVariant(*gregorianDateTime, date); - formatTimeUTC(*gregorianDateTime, time); - return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); - // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) + 4 (. + 3 digits for milliseconds) - // 6 for formatting and one for null termination = 27. We add one extra character to allow us to force null termination. - char buffer[28]; - snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + gregorianDateTime->year, gregorianDateTime->month + 1, gregorianDateTime->monthDay, gregorianDateTime->hour, gregorianDateTime->minute, gregorianDateTime->second, static_cast<int>(fmod(thisDateObj->internalNumber(), 1000))); - buffer[sizeof(buffer) - 1] = 0; - return JSValue::encode(jsNontrivialString(exec, buffer)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); - DateConversionBuffer date; - formatDate(*gregorianDateTime, date); - return JSValue::encode(jsNontrivialString(exec, date)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); - DateConversionBuffer time; - formatTime(*gregorianDateTime, time); - return JSValue::encode(jsNontrivialString(exec, time)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - return JSValue::encode(formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDateAndTime)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - return JSValue::encode(formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDate)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - return JSValue::encode(formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleTime)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - return JSValue::encode(asDateInstance(thisValue)->internalValue()); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(1900 + gregorianDateTime->year)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(1900 + gregorianDateTime->year)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); - DateConversionBuffer date; - DateConversionBuffer time; - formatDateUTCVariant(*gregorianDateTime, date); - formatTimeUTC(*gregorianDateTime, time); - return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->month)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->month)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->monthDay)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->monthDay)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->weekDay)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->weekDay)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->hour)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->hour)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->minute)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->minute)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->second)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(gregorianDateTime->second)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return JSValue::encode(jsNaN()); - - double secs = floor(milli / msPerSecond); - double ms = milli - secs * msPerSecond; - return JSValue::encode(jsNumber(ms)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - if (isnan(milli)) - return JSValue::encode(jsNaN()); - - double secs = floor(milli / msPerSecond); - double ms = milli - secs * msPerSecond; - return JSValue::encode(jsNumber(ms)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(-gregorianDateTime->utcOffset / minutesPerHour)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - double milli = timeClip(exec->argument(0).toNumber(exec)); - JSValue result = jsNumber(milli); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); -} - -static EncodedJSValue setNewValueFromTimeArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - double milli = thisDateObj->internalNumber(); - - if (!exec->argumentCount() || isnan(milli)) { - JSValue result = jsNaN(); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); - } - - double secs = floor(milli / msPerSecond); - double ms = milli - secs * msPerSecond; - - const GregorianDateTime* other = inputIsUTC - ? thisDateObj->gregorianDateTimeUTC(exec) - : thisDateObj->gregorianDateTime(exec); - if (!other) - return JSValue::encode(jsNaN()); - - GregorianDateTime gregorianDateTime; - gregorianDateTime.copyFrom(*other); - if (!fillStructuresUsingTimeArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) { - JSValue result = jsNaN(); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); - } - - JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC)); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); -} - -static EncodedJSValue setNewValueFromDateArgs(ExecState* exec, int numArgsToUse, bool inputIsUTC) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - if (!exec->argumentCount()) { - JSValue result = jsNaN(); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); - } - - double milli = thisDateObj->internalNumber(); - double ms = 0; - - GregorianDateTime gregorianDateTime; - if (numArgsToUse == 3 && isnan(milli)) - msToGregorianDateTime(exec, 0, true, gregorianDateTime); - else { - ms = milli - floor(milli / msPerSecond) * msPerSecond; - const GregorianDateTime* other = inputIsUTC - ? thisDateObj->gregorianDateTimeUTC(exec) - : thisDateObj->gregorianDateTime(exec); - if (!other) - return JSValue::encode(jsNaN()); - gregorianDateTime.copyFrom(*other); - } - - if (!fillStructuresUsingDateArgs(exec, numArgsToUse, &ms, &gregorianDateTime)) { - JSValue result = jsNaN(); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); - } - - JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC)); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromTimeArgs(exec, 1, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromTimeArgs(exec, 1, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromTimeArgs(exec, 2, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromTimeArgs(exec, 2, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromTimeArgs(exec, 3, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromTimeArgs(exec, 3, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromTimeArgs(exec, 4, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromTimeArgs(exec, 4, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromDateArgs(exec, 1, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromDateArgs(exec, 1, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromDateArgs(exec, 2, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromDateArgs(exec, 2, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState* exec) -{ - const bool inputIsUTC = false; - return setNewValueFromDateArgs(exec, 3, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec) -{ - const bool inputIsUTC = true; - return setNewValueFromDateArgs(exec, 3, inputIsUTC); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - if (!exec->argumentCount()) { - JSValue result = jsNaN(); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); - } - - double milli = thisDateObj->internalNumber(); - double ms = 0; - - GregorianDateTime gregorianDateTime; - if (isnan(milli)) - // Based on ECMA 262 B.2.5 (setYear) - // the time must be reset to +0 if it is NaN. - msToGregorianDateTime(exec, 0, true, gregorianDateTime); - else { - double secs = floor(milli / msPerSecond); - ms = milli - secs * msPerSecond; - if (const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec)) - gregorianDateTime.copyFrom(*other); - } - - double year = exec->argument(0).toIntegerPreserveNaN(exec); - if (!isfinite(year)) { - JSValue result = jsNaN(); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); - } - - gregorianDateTime.year = toInt32((year > 99 || year < 0) ? year - 1900 : year); - JSValue result = jsNumber(gregorianDateTimeToMS(exec, gregorianDateTime, ms, false)); - thisDateObj->setInternalValue(result); - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&DateInstance::info)) - return throwVMTypeError(exec); - - DateInstance* thisDateObj = asDateInstance(thisValue); - - const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); - if (!gregorianDateTime) - return JSValue::encode(jsNaN()); - - // NOTE: IE returns the full year even in getYear. - return JSValue::encode(jsNumber(gregorianDateTime->year)); -} - -EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - JSObject* object = thisValue.toThisObject(exec); - if (exec->hadException()) - return JSValue::encode(jsNull()); - - JSValue toISOValue = object->get(exec, exec->globalData().propertyNames->toISOString); - if (exec->hadException()) - return JSValue::encode(jsNull()); - - CallData callData; - CallType callType = getCallData(toISOValue, callData); - if (callType == CallTypeNone) - return throwVMError(exec, createTypeError(exec, "toISOString is not a function")); - - JSValue result = call(exec, asObject(toISOValue), callType, callData, object, exec->emptyList()); - if (exec->hadException()) - return JSValue::encode(jsNull()); - if (result.isObject()) - return throwVMError(exec, createTypeError(exec, "toISOString did not return a primitive value")); - return JSValue::encode(result); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/DatePrototype.h b/JavaScriptCore/runtime/DatePrototype.h deleted file mode 100644 index e3672aa..0000000 --- a/JavaScriptCore/runtime/DatePrototype.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef DatePrototype_h -#define DatePrototype_h - -#include "DateInstance.h" - -namespace JSC { - - class ObjectPrototype; - - class DatePrototype : public DateInstance { - public: - DatePrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags; - - }; - -} // namespace JSC - -#endif // DatePrototype_h diff --git a/JavaScriptCore/runtime/Error.cpp b/JavaScriptCore/runtime/Error.cpp deleted file mode 100644 index 227e9ec..0000000 --- a/JavaScriptCore/runtime/Error.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Eric Seidel (eric@webkit.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "Error.h" - -#include "ConstructData.h" -#include "ErrorConstructor.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "JSObject.h" -#include "JSString.h" -#include "NativeErrorConstructor.h" -#include "SourceCode.h" - -namespace JSC { - -static const char* linePropertyName = "line"; -static const char* sourceIdPropertyName = "sourceId"; -static const char* sourceURLPropertyName = "sourceURL"; - -JSObject* createError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->errorStructure(), message); -} - -JSObject* createEvalError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->evalErrorConstructor()->errorStructure(), message); -} - -JSObject* createRangeError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->rangeErrorConstructor()->errorStructure(), message); -} - -JSObject* createReferenceError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->referenceErrorConstructor()->errorStructure(), message); -} - -JSObject* createSyntaxError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->syntaxErrorConstructor()->errorStructure(), message); -} - -JSObject* createTypeError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->typeErrorConstructor()->errorStructure(), message); -} - -JSObject* createURIError(JSGlobalObject* globalObject, const UString& message) -{ - ASSERT(!message.isEmpty()); - return ErrorInstance::create(&globalObject->globalData(), globalObject->URIErrorConstructor()->errorStructure(), message); -} - -JSObject* createError(ExecState* exec, const UString& message) -{ - return createError(exec->lexicalGlobalObject(), message); -} - -JSObject* createEvalError(ExecState* exec, const UString& message) -{ - return createEvalError(exec->lexicalGlobalObject(), message); -} - -JSObject* createRangeError(ExecState* exec, const UString& message) -{ - return createRangeError(exec->lexicalGlobalObject(), message); -} - -JSObject* createReferenceError(ExecState* exec, const UString& message) -{ - return createReferenceError(exec->lexicalGlobalObject(), message); -} - -JSObject* createSyntaxError(ExecState* exec, const UString& message) -{ - return createSyntaxError(exec->lexicalGlobalObject(), message); -} - -JSObject* createTypeError(ExecState* exec, const UString& message) -{ - return createTypeError(exec->lexicalGlobalObject(), message); -} - -JSObject* createURIError(ExecState* exec, const UString& message) -{ - return createURIError(exec->lexicalGlobalObject(), message); -} - -JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source) -{ - intptr_t sourceID = source.provider()->asID(); - const UString& sourceURL = source.provider()->url(); - - if (line != -1) - error->putWithAttributes(globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete); - if (sourceID != -1) - error->putWithAttributes(globalData, Identifier(globalData, sourceIdPropertyName), jsNumber((double)sourceID), ReadOnly | DontDelete); - if (!sourceURL.isNull()) - error->putWithAttributes(globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete); - - return error; -} - -JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source) -{ - return addErrorInfo(&exec->globalData(), error, line, source); -} - -bool hasErrorInfo(ExecState* exec, JSObject* error) -{ - return error->hasProperty(exec, Identifier(exec, linePropertyName)) - || error->hasProperty(exec, Identifier(exec, sourceIdPropertyName)) - || error->hasProperty(exec, Identifier(exec, sourceURLPropertyName)); -} - -JSValue throwError(ExecState* exec, JSValue error) -{ - exec->globalData().exception = error; - return error; -} - -JSObject* throwError(ExecState* exec, JSObject* error) -{ - exec->globalData().exception = error; - return error; -} - -JSObject* throwTypeError(ExecState* exec) -{ - return throwError(exec, createTypeError(exec, "Type error")); -} - -JSObject* throwSyntaxError(ExecState* exec) -{ - return throwError(exec, createSyntaxError(exec, "Syntax error")); -} - -class StrictModeTypeErrorFunction : public InternalFunction { -public: - StrictModeTypeErrorFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& message) - : InternalFunction(&exec->globalData(), globalObject, structure, exec->globalData().propertyNames->emptyIdentifier) - , m_message(message) - { - } - - static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec) - { - throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message); - return JSValue::encode(jsNull()); - } - - ConstructType getConstructData(ConstructData& constructData) - { - constructData.native.function = constructThrowTypeError; - return ConstructTypeHost; - } - - static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec) - { - throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message); - return JSValue::encode(jsNull()); - } - - CallType getCallData(CallData& callData) - { - callData.native.function = callThrowTypeError; - return CallTypeHost; - } - -private: - UString m_message; -}; - -COMPILE_ASSERT(sizeof(StrictModeTypeErrorFunction) <= sizeof(CollectorCell), sizeof_StrictModeTypeErrorFunction_must_be_less_than_CollectorCell); - -JSValue createTypeErrorFunction(ExecState* exec, const UString& message) -{ - return new (exec) StrictModeTypeErrorFunction(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->internalFunctionStructure(), message); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Error.h b/JavaScriptCore/runtime/Error.h deleted file mode 100644 index c0f9d32..0000000 --- a/JavaScriptCore/runtime/Error.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Error_h -#define Error_h - -#include "JSObject.h" -#include <stdint.h> - -namespace JSC { - - class ExecState; - class JSGlobalData; - class JSGlobalObject; - class JSObject; - class SourceCode; - class Structure; - class UString; - - // Methods to create a range of internal errors. - JSObject* createError(JSGlobalObject*, const UString&); - JSObject* createEvalError(JSGlobalObject*, const UString&); - JSObject* createRangeError(JSGlobalObject*, const UString&); - JSObject* createReferenceError(JSGlobalObject*, const UString&); - JSObject* createSyntaxError(JSGlobalObject*, const UString&); - JSObject* createTypeError(JSGlobalObject*, const UString&); - JSObject* createURIError(JSGlobalObject*, const UString&); - // ExecState wrappers. - JSObject* createError(ExecState*, const UString&); - JSObject* createEvalError(ExecState*, const UString&); - JSObject* createRangeError(ExecState*, const UString&); - JSObject* createReferenceError(ExecState*, const UString&); - JSObject* createSyntaxError(ExecState*, const UString&); - JSObject* createTypeError(ExecState*, const UString&); - JSObject* createURIError(ExecState*, const UString&); - - // Methods to add - bool hasErrorInfo(ExecState*, JSObject* error); - JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&); - // ExecState wrappers. - JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&); - - // Methods to throw Errors. - JSValue throwError(ExecState*, JSValue); - JSObject* throwError(ExecState*, JSObject*); - - // Convenience wrappers, create an throw an exception with a default message. - JSObject* throwTypeError(ExecState*); - JSObject* throwSyntaxError(ExecState*); - - // Convenience wrappers, wrap result as an EncodedJSValue. - inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(throwError(exec, error)); } - inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); } - - JSValue createTypeErrorFunction(ExecState* exec, const UString& message); - -} // namespace JSC - -#endif // Error_h diff --git a/JavaScriptCore/runtime/ErrorConstructor.cpp b/JavaScriptCore/runtime/ErrorConstructor.cpp deleted file mode 100644 index 4326a4d..0000000 --- a/JavaScriptCore/runtime/ErrorConstructor.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "ErrorConstructor.h" - -#include "ErrorPrototype.h" -#include "JSGlobalObject.h" -#include "JSString.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor); - -ErrorConstructor::ErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, ErrorPrototype* errorPrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, errorPrototype->classInfo()->className)) -{ - // ECMA 15.11.3.1 Error.prototype - putDirectWithoutTransition(exec->propertyNames().prototype, errorPrototype, DontEnum | DontDelete | ReadOnly); - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); -} - -// ECMA 15.9.3 - -static EncodedJSValue JSC_HOST_CALL constructWithErrorConstructor(ExecState* exec) -{ - JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined(); - Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure(); - return JSValue::encode(ErrorInstance::create(exec, errorStructure, message)); -} - -ConstructType ErrorConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithErrorConstructor; - return ConstructTypeHost; -} - -static EncodedJSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec) -{ - JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined(); - Structure* errorStructure = exec->lexicalGlobalObject()->errorStructure(); - return JSValue::encode(ErrorInstance::create(exec, errorStructure, message)); -} - -CallType ErrorConstructor::getCallData(CallData& callData) -{ - callData.native.function = callErrorConstructor; - return CallTypeHost; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ErrorConstructor.h b/JavaScriptCore/runtime/ErrorConstructor.h deleted file mode 100644 index 3d0d706..0000000 --- a/JavaScriptCore/runtime/ErrorConstructor.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ErrorConstructor_h -#define ErrorConstructor_h - -#include "ErrorInstance.h" -#include "InternalFunction.h" - -namespace JSC { - - class ErrorPrototype; - - class ErrorConstructor : public InternalFunction { - public: - ErrorConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, ErrorPrototype*); - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - -} // namespace JSC - -#endif // ErrorConstructor_h diff --git a/JavaScriptCore/runtime/ErrorInstance.cpp b/JavaScriptCore/runtime/ErrorInstance.cpp deleted file mode 100644 index 0f3153c..0000000 --- a/JavaScriptCore/runtime/ErrorInstance.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "ErrorInstance.h" - -namespace JSC { - -const ClassInfo ErrorInstance::info = { "Error", 0, 0, 0 }; - -ErrorInstance::ErrorInstance(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure) - : JSObject(structure) - , m_appendSourceToMessage(false) -{ - putDirect(globalData->propertyNames->message, jsString(globalData, "")); -} - -ErrorInstance::ErrorInstance(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const UString& message) - : JSObject(structure) - , m_appendSourceToMessage(false) -{ - putDirect(globalData->propertyNames->message, jsString(globalData, message)); -} - -ErrorInstance* ErrorInstance::create(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const UString& message) -{ - return new (globalData) ErrorInstance(globalData, structure, message); -} - -ErrorInstance* ErrorInstance::create(ExecState* exec, NonNullPassRefPtr<Structure> structure, JSValue message) -{ - if (message.isUndefined()) - return new (exec) ErrorInstance(&exec->globalData(), structure); - return new (exec) ErrorInstance(&exec->globalData(), structure, message.toString(exec)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ErrorInstance.h b/JavaScriptCore/runtime/ErrorInstance.h deleted file mode 100644 index b3bebec..0000000 --- a/JavaScriptCore/runtime/ErrorInstance.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ErrorInstance_h -#define ErrorInstance_h - -#include "JSObject.h" - -namespace JSC { - - class ErrorInstance : public JSObject { - public: - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - static ErrorInstance* create(JSGlobalData*, NonNullPassRefPtr<Structure>, const UString&); - static ErrorInstance* create(ExecState* exec, NonNullPassRefPtr<Structure>, JSValue message); - - - bool appendSourceToMessage() { return m_appendSourceToMessage; } - void setAppendSourceToMessage() { m_appendSourceToMessage = true; } - void clearAppendSourceToMessage() { m_appendSourceToMessage = false; } - - virtual bool isErrorInstance() const { return true; } - - protected: - explicit ErrorInstance(JSGlobalData*, NonNullPassRefPtr<Structure>); - explicit ErrorInstance(JSGlobalData*, NonNullPassRefPtr<Structure>, const UString&); - - bool m_appendSourceToMessage; - }; - -} // namespace JSC - -#endif // ErrorInstance_h diff --git a/JavaScriptCore/runtime/ErrorPrototype.cpp b/JavaScriptCore/runtime/ErrorPrototype.cpp deleted file mode 100644 index d18e7d8..0000000 --- a/JavaScriptCore/runtime/ErrorPrototype.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "ErrorPrototype.h" - -#include "JSFunction.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "ObjectPrototype.h" -#include "PrototypeFunction.h" -#include "UString.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype); - -static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*); - -// ECMA 15.9.4 -ErrorPrototype::ErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure) - : ErrorInstance(&exec->globalData(), structure) -{ - // The constructor will be added later in ErrorConstructor's constructor - - putDirectWithoutTransition(exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum); -} - -EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec) -{ - JSObject* thisObj = exec->hostThisValue().toThisObject(exec); - JSValue name = thisObj->get(exec, exec->propertyNames().name); - JSValue message = thisObj->get(exec, exec->propertyNames().message); - - // Mozilla-compatible format. - - if (!name.isUndefined()) { - if (!message.isUndefined()) - return JSValue::encode(jsMakeNontrivialString(exec, name.toString(exec), ": ", message.toString(exec))); - return JSValue::encode(jsNontrivialString(exec, name.toString(exec))); - } - if (!message.isUndefined()) - return JSValue::encode(jsMakeNontrivialString(exec, "Error: ", message.toString(exec))); - return JSValue::encode(jsNontrivialString(exec, "Error")); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ErrorPrototype.h b/JavaScriptCore/runtime/ErrorPrototype.h deleted file mode 100644 index fce2742..0000000 --- a/JavaScriptCore/runtime/ErrorPrototype.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ErrorPrototype_h -#define ErrorPrototype_h - -#include "ErrorInstance.h" - -namespace JSC { - - class ObjectPrototype; - - class ErrorPrototype : public ErrorInstance { - public: - ErrorPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure); - }; - -} // namespace JSC - -#endif // ErrorPrototype_h diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp deleted file mode 100644 index 1ef264c..0000000 --- a/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ExceptionHelpers.h" - -#include "CodeBlock.h" -#include "CallFrame.h" -#include "ErrorInstance.h" -#include "JSGlobalObjectFunctions.h" -#include "JSObject.h" -#include "JSNotAnObject.h" -#include "Interpreter.h" -#include "Nodes.h" -#include "UStringConcatenate.h" - -namespace JSC { - -class InterruptedExecutionError : public JSObject { -public: - InterruptedExecutionError(JSGlobalData* globalData) - : JSObject(globalData->interruptedExecutionErrorStructure) - { - } - - virtual ComplType exceptionType() const { return Interrupted; } - - virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; } -}; - -JSObject* createInterruptedExecutionException(JSGlobalData* globalData) -{ - return new (globalData) InterruptedExecutionError(globalData); -} - -class TerminatedExecutionError : public JSObject { -public: - TerminatedExecutionError(JSGlobalData* globalData) - : JSObject(globalData->terminatedExecutionErrorStructure) - { - } - - virtual ComplType exceptionType() const { return Terminated; } - - virtual UString toString(ExecState*) const { return "JavaScript execution terminated."; } -}; - -JSObject* createTerminatedExecutionException(JSGlobalData* globalData) -{ - return new (globalData) TerminatedExecutionError(globalData); -} - -JSObject* createStackOverflowError(ExecState* exec) -{ - return createRangeError(exec, "Maximum call stack size exceeded."); -} - -JSObject* createStackOverflowError(JSGlobalObject* globalObject) -{ - return createRangeError(globalObject, "Maximum call stack size exceeded."); -} - -JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident) -{ - UString message(makeUString("Can't find variable: ", ident.ustring())); - return createReferenceError(exec, message); -} - -JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value) -{ - UString errorMessage = makeUString("'", value.toString(exec), "' is not a valid argument for '", op, "'"); - JSObject* exception = createTypeError(exec, errorMessage); - ASSERT(exception->isErrorInstance()); - static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); - return exception; -} - -JSObject* createNotAConstructorError(ExecState* exec, JSValue value) -{ - UString errorMessage = makeUString("'", value.toString(exec), "' is not a constructor"); - JSObject* exception = createTypeError(exec, errorMessage); - ASSERT(exception->isErrorInstance()); - static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); - return exception; -} - -JSObject* createNotAFunctionError(ExecState* exec, JSValue value) -{ - UString errorMessage = makeUString("'", value.toString(exec), "' is not a function"); - JSObject* exception = createTypeError(exec, errorMessage); - ASSERT(exception->isErrorInstance()); - static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); - return exception; -} - -JSObject* createNotAnObjectError(ExecState* exec, JSValue value) -{ - UString errorMessage = makeUString("'", value.toString(exec), "' is not an object"); - JSObject* exception = createTypeError(exec, errorMessage); - ASSERT(exception->isErrorInstance()); - static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); - return exception; -} - -JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const UString& propertyName) -{ - return createReferenceError(exec, makeUString("Strict mode forbids implicit creation of global property '", propertyName, "'")); -} - -JSObject* throwOutOfMemoryError(ExecState* exec) -{ - return throwError(exec, createError(exec, "Out of memory")); -} - -JSObject* throwStackOverflowError(ExecState* exec) -{ - return throwError(exec, createStackOverflowError(exec)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h deleted file mode 100644 index 7edffad..0000000 --- a/JavaScriptCore/runtime/ExceptionHelpers.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ExceptionHelpers_h -#define ExceptionHelpers_h - -#include "JSValue.h" - -namespace JSC { - - class CodeBlock; - class ExecState; - class Identifier; - class JSGlobalData; - class JSGlobalObject; - class JSNotAnObjectErrorStub; - class JSObject; - class Node; - struct Instruction; - - JSObject* createInterruptedExecutionException(JSGlobalData*); - JSObject* createTerminatedExecutionException(JSGlobalData*); - JSObject* createStackOverflowError(ExecState*); - JSObject* createStackOverflowError(JSGlobalObject*); - JSObject* createUndefinedVariableError(ExecState*, const Identifier&); - JSObject* createNotAnObjectError(ExecState*, JSValue); - JSObject* createInvalidParamError(ExecState*, const char* op, JSValue); - JSObject* createNotAConstructorError(ExecState*, JSValue); - JSObject* createNotAFunctionError(ExecState*, JSValue); - JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const UString&); - - JSObject* throwOutOfMemoryError(ExecState*); - JSObject* throwStackOverflowError(ExecState*); - -} // namespace JSC - -#endif // ExceptionHelpers_h diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp deleted file mode 100644 index c7262be..0000000 --- a/JavaScriptCore/runtime/Executable.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2009, 2010 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 "Executable.h" - -#include "BytecodeGenerator.h" -#include "CodeBlock.h" -#include "JIT.h" -#include "Parser.h" -#include "UStringBuilder.h" -#include "Vector.h" - -namespace JSC { - -#if ENABLE(JIT) -NativeExecutable::~NativeExecutable() -{ -} -#endif - -VPtrHackExecutable::~VPtrHackExecutable() -{ -} - -EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext) - : ScriptExecutable(exec, source, inStrictContext) -{ -} - -EvalExecutable::~EvalExecutable() -{ -} - -ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source) - : ScriptExecutable(exec, source, false) -{ -} - -ProgramExecutable::~ProgramExecutable() -{ -} - -FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine) - : ScriptExecutable(globalData, source, inStrictContext) - , m_numCapturedVariables(0) - , m_forceUsesArguments(forceUsesArguments) - , m_parameters(parameters) - , m_name(name) - , m_symbolTable(0) -{ - m_firstLine = firstLine; - m_lastLine = lastLine; -} - -FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine) - : ScriptExecutable(exec, source, inStrictContext) - , m_numCapturedVariables(0) - , m_forceUsesArguments(forceUsesArguments) - , m_parameters(parameters) - , m_name(name) - , m_symbolTable(0) -{ - m_firstLine = firstLine; - m_lastLine = lastLine; -} - -FunctionExecutable::~FunctionExecutable() -{ -} - -JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode) -{ - JSObject* exception = 0; - JSGlobalData* globalData = &exec->globalData(); - JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); - if (!evalNode) { - ASSERT(exception); - return exception; - } - recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - ASSERT(!m_evalCodeBlock); - m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get()))); - generator->generate(); - - evalNode->destroyData(); - -#if ENABLE(JIT) - if (exec->globalData().canUseJIT()) { - m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_evalCodeBlock.get()); -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_evalCodeBlock->discardBytecode(); -#endif - } -#endif - - return 0; -} - -JSObject* ProgramExecutable::checkSyntax(ExecState* exec) -{ - JSObject* exception = 0; - JSGlobalData* globalData = &exec->globalData(); - JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, JSParseNormal, &exception); - if (programNode) - return 0; - ASSERT(exception); - return exception; -} - -JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode) -{ - ASSERT(!m_programCodeBlock); - - JSObject* exception = 0; - JSGlobalData* globalData = &exec->globalData(); - JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception); - if (!programNode) { - ASSERT(exception); - return exception; - } - recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider())); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock.get()))); - generator->generate(); - - programNode->destroyData(); - -#if ENABLE(JIT) - if (exec->globalData().canUseJIT()) { - m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get()); -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_programCodeBlock->discardBytecode(); -#endif - } -#endif - - return 0; -} - -JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode) -{ - JSObject* exception = 0; - JSGlobalData* globalData = scopeChainNode->globalData; - RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); - if (!body) { - ASSERT(exception); - return exception; - } - if (m_forceUsesArguments) - body->setUsesArguments(); - body->finishParsing(m_parameters, m_name); - recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - ASSERT(!m_codeBlockForCall); - m_codeBlockForCall = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), false)); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChain, m_codeBlockForCall->symbolTable(), m_codeBlockForCall.get()))); - generator->generate(); - m_numParametersForCall = m_codeBlockForCall->m_numParameters; - ASSERT(m_numParametersForCall); - m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars; - m_symbolTable = m_codeBlockForCall->sharedSymbolTable(); - - body->destroyData(); - -#if ENABLE(JIT) - if (exec->globalData().canUseJIT()) { - m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck); -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_codeBlockForCall->discardBytecode(); -#endif - } -#endif - - return 0; -} - -JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode) -{ - JSObject* exception = 0; - JSGlobalData* globalData = scopeChainNode->globalData; - RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception); - if (!body) { - ASSERT(exception); - return exception; - } - if (m_forceUsesArguments) - body->setUsesArguments(); - body->finishParsing(m_parameters, m_name); - recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); - - ScopeChain scopeChain(scopeChainNode); - JSGlobalObject* globalObject = scopeChain.globalObject(); - - ASSERT(!m_codeBlockForConstruct); - m_codeBlockForConstruct = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), true)); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct.get()))); - generator->generate(); - m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters; - ASSERT(m_numParametersForConstruct); - m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars; - m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable(); - - body->destroyData(); - -#if ENABLE(JIT) - if (exec->globalData().canUseJIT()) { - m_jitCodeForConstruct = JIT::compile(scopeChainNode->globalData, m_codeBlockForConstruct.get(), &m_jitCodeForConstructWithArityCheck); -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_codeBlockForConstruct->discardBytecode(); -#endif - } -#endif - - return 0; -} - -void FunctionExecutable::markAggregate(MarkStack& markStack) -{ - if (m_codeBlockForCall) - m_codeBlockForCall->markAggregate(markStack); - if (m_codeBlockForConstruct) - m_codeBlockForConstruct->markAggregate(markStack); -} - -void FunctionExecutable::discardCode() -{ - m_codeBlockForCall.clear(); - m_codeBlockForConstruct.clear(); - m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED; - m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED; -#if ENABLE(JIT) - m_jitCodeForCall = JITCode(); - m_jitCodeForConstruct = JITCode(); -#endif -} - -PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) -{ - JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception); - if (!program) { - ASSERT(*exception); - return 0; - } - - // Uses of this function that would not result in a single function expression are invalid. - StatementNode* exprStatement = program->singleStatement(); - ASSERT(exprStatement); - ASSERT(exprStatement->isExprStatement()); - ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr(); - ASSERT(funcExpr); - ASSERT(funcExpr->isFuncExprNode()); - FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); - ASSERT(body); - - return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine()); -} - -UString FunctionExecutable::paramString() const -{ - FunctionParameters& parameters = *m_parameters; - UStringBuilder builder; - for (size_t pos = 0; pos < parameters.size(); ++pos) { - if (!builder.isEmpty()) - builder.append(", "); - builder.append(parameters[pos].ustring()); - } - return builder.toUString(); -} - -} diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h deleted file mode 100644 index 544e487..0000000 --- a/JavaScriptCore/runtime/Executable.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2009, 2010 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 Executable_h -#define Executable_h - -#include "CallData.h" -#include "JSFunction.h" -#include "Interpreter.h" -#include "Nodes.h" -#include "SamplingTool.h" -#include <wtf/PassOwnPtr.h> - -namespace JSC { - - class CodeBlock; - class Debugger; - class EvalCodeBlock; - class FunctionCodeBlock; - class ProgramCodeBlock; - class ScopeChainNode; - - struct ExceptionInfo; - - class ExecutableBase : public RefCounted<ExecutableBase> { - friend class JIT; - - protected: - static const int NUM_PARAMETERS_IS_HOST = 0; - static const int NUM_PARAMETERS_NOT_COMPILED = -1; - - public: - ExecutableBase(int numParameters) - : m_numParametersForCall(numParameters) - , m_numParametersForConstruct(numParameters) - { - } - - virtual ~ExecutableBase() {} - - bool isHostFunction() const - { - ASSERT((m_numParametersForCall == NUM_PARAMETERS_IS_HOST) == (m_numParametersForConstruct == NUM_PARAMETERS_IS_HOST)); - return m_numParametersForCall == NUM_PARAMETERS_IS_HOST; - } - - protected: - int m_numParametersForCall; - int m_numParametersForConstruct; - -#if ENABLE(JIT) - public: - JITCode& generatedJITCodeForCall() - { - ASSERT(m_jitCodeForCall); - return m_jitCodeForCall; - } - - JITCode& generatedJITCodeForConstruct() - { - ASSERT(m_jitCodeForConstruct); - return m_jitCodeForConstruct; - } - - protected: - JITCode m_jitCodeForCall; - JITCode m_jitCodeForConstruct; - MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck; - MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck; -#endif - }; - -#if ENABLE(JIT) - class NativeExecutable : public ExecutableBase { - friend class JIT; - public: - static PassRefPtr<NativeExecutable> create(MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor) - { - if (!callThunk) - return adoptRef(new NativeExecutable(JITCode(), function, JITCode(), constructor)); - return adoptRef(new NativeExecutable(JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor)); - } - - ~NativeExecutable(); - - NativeFunction function() { return m_function; } - - private: - NativeExecutable(JITCode callThunk, NativeFunction function, JITCode constructThunk, NativeFunction constructor) - : ExecutableBase(NUM_PARAMETERS_IS_HOST) - , m_function(function) - , m_constructor(constructor) - { - m_jitCodeForCall = callThunk; - m_jitCodeForConstruct = constructThunk; - m_jitCodeForCallWithArityCheck = callThunk.addressForCall(); - m_jitCodeForConstructWithArityCheck = constructThunk.addressForCall(); - } - - NativeFunction m_function; - // Probably should be a NativeConstructor, but this will currently require rewriting the JIT - // trampoline. It may be easier to make NativeFunction be passed 'this' as a part of the ArgList. - NativeFunction m_constructor; - }; -#endif - - class VPtrHackExecutable : public ExecutableBase { - public: - VPtrHackExecutable() - : ExecutableBase(NUM_PARAMETERS_IS_HOST) - { - } - - ~VPtrHackExecutable(); - }; - - class ScriptExecutable : public ExecutableBase { - public: - ScriptExecutable(JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext) - : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) - , m_source(source) - , m_features(isInStrictContext ? StrictModeFeature : 0) - { -#if ENABLE(CODEBLOCK_SAMPLING) - relaxAdoptionRequirement(); - if (SamplingTool* sampler = globalData->interpreter->sampler()) - sampler->notifyOfScope(this); -#else - UNUSED_PARAM(globalData); -#endif - } - - ScriptExecutable(ExecState* exec, const SourceCode& source, bool isInStrictContext) - : ExecutableBase(NUM_PARAMETERS_NOT_COMPILED) - , m_source(source) - , m_features(isInStrictContext ? StrictModeFeature : 0) - { -#if ENABLE(CODEBLOCK_SAMPLING) - relaxAdoptionRequirement(); - if (SamplingTool* sampler = exec->globalData().interpreter->sampler()) - sampler->notifyOfScope(this); -#else - UNUSED_PARAM(exec); -#endif - } - - const SourceCode& source() { return m_source; } - intptr_t sourceID() const { return m_source.provider()->asID(); } - const UString& sourceURL() const { return m_source.provider()->url(); } - int lineNo() const { return m_firstLine; } - int lastLine() const { return m_lastLine; } - - bool usesEval() const { return m_features & EvalFeature; } - bool usesArguments() const { return m_features & ArgumentsFeature; } - bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); } - bool isStrictMode() const { return m_features & StrictModeFeature; } - - protected: - void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine) - { - m_features = features; - m_hasCapturedVariables = hasCapturedVariables; - m_firstLine = firstLine; - m_lastLine = lastLine; - } - - SourceCode m_source; - CodeFeatures m_features; - bool m_hasCapturedVariables; - int m_firstLine; - int m_lastLine; - }; - - class EvalExecutable : public ScriptExecutable { - public: - - ~EvalExecutable(); - - JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode) - { - JSObject* error = 0; - if (!m_evalCodeBlock) - error = compileInternal(exec, scopeChainNode); - ASSERT(!error == !!m_evalCodeBlock); - return error; - } - - EvalCodeBlock& generatedBytecode() - { - ASSERT(m_evalCodeBlock); - return *m_evalCodeBlock; - } - - static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return adoptRef(new EvalExecutable(exec, source, isInStrictContext)); } - -#if ENABLE(JIT) - JITCode& generatedJITCode() - { - return generatedJITCodeForCall(); - } -#endif - - private: - EvalExecutable(ExecState*, const SourceCode&, bool); - - JSObject* compileInternal(ExecState*, ScopeChainNode*); - - OwnPtr<EvalCodeBlock> m_evalCodeBlock; - }; - - class ProgramExecutable : public ScriptExecutable { - public: - static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source) - { - return adoptRef(new ProgramExecutable(exec, source)); - } - - ~ProgramExecutable(); - - JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode) - { - JSObject* error = 0; - if (!m_programCodeBlock) - error = compileInternal(exec, scopeChainNode); - ASSERT(!error == !!m_programCodeBlock); - return error; - } - - ProgramCodeBlock& generatedBytecode() - { - ASSERT(m_programCodeBlock); - return *m_programCodeBlock; - } - - JSObject* checkSyntax(ExecState*); - -#if ENABLE(JIT) - JITCode& generatedJITCode() - { - return generatedJITCodeForCall(); - } -#endif - - private: - ProgramExecutable(ExecState*, const SourceCode&); - - JSObject* compileInternal(ExecState*, ScopeChainNode*); - - OwnPtr<ProgramCodeBlock> m_programCodeBlock; - }; - - class FunctionExecutable : public ScriptExecutable { - friend class JIT; - public: - static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) - { - return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine)); - } - - static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) - { - return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine)); - } - - ~FunctionExecutable(); - - JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain) - { - return new (exec) JSFunction(exec, this, scopeChain); - } - - // Returns either call or construct bytecode. This can be appropriate - // for answering questions that that don't vary between call and construct -- - // for example, argumentsRegister(). - FunctionCodeBlock& generatedBytecode() - { - if (m_codeBlockForCall) - return *m_codeBlockForCall; - ASSERT(m_codeBlockForConstruct); - return *m_codeBlockForConstruct; - } - - JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode) - { - JSObject* error = 0; - if (!m_codeBlockForCall) - error = compileForCallInternal(exec, scopeChainNode); - ASSERT(!error == !!m_codeBlockForCall); - return error; - } - - bool isGeneratedForCall() const - { - return m_codeBlockForCall; - } - - FunctionCodeBlock& generatedBytecodeForCall() - { - ASSERT(m_codeBlockForCall); - return *m_codeBlockForCall; - } - - JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode) - { - JSObject* error = 0; - if (!m_codeBlockForConstruct) - error = compileForConstructInternal(exec, scopeChainNode); - ASSERT(!error == !!m_codeBlockForConstruct); - return error; - } - - bool isGeneratedForConstruct() const - { - return m_codeBlockForConstruct; - } - - FunctionCodeBlock& generatedBytecodeForConstruct() - { - ASSERT(m_codeBlockForConstruct); - return *m_codeBlockForConstruct; - } - - const Identifier& name() { return m_name; } - size_t parameterCount() const { return m_parameters->size(); } - unsigned capturedVariableCount() const { return m_numCapturedVariables; } - UString paramString() const; - SharedSymbolTable* symbolTable() const { return m_symbolTable; } - - void discardCode(); - void markAggregate(MarkStack&); - static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception); - - private: - FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine); - FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine); - - JSObject* compileForCallInternal(ExecState*, ScopeChainNode*); - JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*); - - unsigned m_numCapturedVariables : 31; - bool m_forceUsesArguments : 1; - - RefPtr<FunctionParameters> m_parameters; - OwnPtr<FunctionCodeBlock> m_codeBlockForCall; - OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct; - Identifier m_name; - SharedSymbolTable* m_symbolTable; - -#if ENABLE(JIT) - public: - MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck() - { - ASSERT(m_jitCodeForCall); - ASSERT(m_jitCodeForCallWithArityCheck); - return m_jitCodeForCallWithArityCheck; - } - - MacroAssemblerCodePtr generatedJITCodeForConstructWithArityCheck() - { - ASSERT(m_jitCodeForConstruct); - ASSERT(m_jitCodeForConstructWithArityCheck); - return m_jitCodeForConstructWithArityCheck; - } -#endif - }; - - inline FunctionExecutable* JSFunction::jsExecutable() const - { - ASSERT(!isHostFunctionNonInline()); - return static_cast<FunctionExecutable*>(m_executable.get()); - } - - inline bool JSFunction::isHostFunction() const - { - ASSERT(m_executable); - return m_executable->isHostFunction(); - } - -#if ENABLE(JIT) - inline NativeFunction JSFunction::nativeFunction() - { - ASSERT(isHostFunction()); - return static_cast<NativeExecutable*>(m_executable.get())->function(); - } -#endif -} - -#endif diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp deleted file mode 100644 index 45b4802..0000000 --- a/JavaScriptCore/runtime/FunctionConstructor.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "FunctionConstructor.h" - -#include "Debugger.h" -#include "ExceptionHelpers.h" -#include "FunctionPrototype.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "JSString.h" -#include "Lexer.h" -#include "Nodes.h" -#include "Parser.h" -#include "UStringBuilder.h" -#include "UStringConcatenate.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor); - -FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, FunctionPrototype* functionPrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, functionPrototype->classInfo()->className)) -{ - putDirectWithoutTransition(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly); - - // Number of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum); -} - -static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructFunction(exec, args)); -} - -ConstructType FunctionConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithFunctionConstructor; - return ConstructTypeHost; -} - -static EncodedJSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructFunction(exec, args)); -} - -// ECMA 15.3.1 The Function Constructor Called as a Function -CallType FunctionConstructor::getCallData(CallData& callData) -{ - callData.native.function = callFunctionConstructor; - return CallTypeHost; -} - -// ECMA 15.3.2 The Function Constructor -JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) -{ - // Functions need to have a space following the opening { due to for web compatibility - // see https://bugs.webkit.org/show_bug.cgi?id=24350 - // We also need \n before the closing } to handle // comments at the end of the last line - UString program; - if (args.isEmpty()) - program = "(function() { \n})"; - else if (args.size() == 1) - program = makeUString("(function() { ", args.at(0).toString(exec), "\n})"); - else { - UStringBuilder builder; - builder.append("(function("); - builder.append(args.at(0).toString(exec)); - for (size_t i = 1; i < args.size() - 1; i++) { - builder.append(","); - builder.append(args.at(i).toString(exec)); - } - builder.append(") { "); - builder.append(args.at(args.size() - 1).toString(exec)); - builder.append("\n})"); - program = builder.toUString(); - } - - JSGlobalObject* globalObject = exec->lexicalGlobalObject(); - JSGlobalData& globalData = globalObject->globalData(); - SourceCode source = makeSource(program, sourceURL, lineNumber); - JSObject* exception = 0; - RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception); - if (!function) { - ASSERT(exception); - return throwError(exec, exception); - } - - ScopeChain scopeChain(globalObject, &globalData, globalObject, exec->globalThisValue()); - return new (exec) JSFunction(exec, function, scopeChain.node()); -} - -// ECMA 15.3.2 The Function Constructor -JSObject* constructFunction(ExecState* exec, const ArgList& args) -{ - return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/FunctionConstructor.h b/JavaScriptCore/runtime/FunctionConstructor.h deleted file mode 100644 index 6af4861..0000000 --- a/JavaScriptCore/runtime/FunctionConstructor.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef FunctionConstructor_h -#define FunctionConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class FunctionPrototype; - - class FunctionConstructor : public InternalFunction { - public: - FunctionConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, FunctionPrototype*); - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - - JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber); - JSObject* constructFunction(ExecState*, const ArgList&); - -} // namespace JSC - -#endif // FunctionConstructor_h diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp deleted file mode 100644 index cd7739d..0000000 --- a/JavaScriptCore/runtime/FunctionPrototype.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "FunctionPrototype.h" - -#include "Arguments.h" -#include "JSArray.h" -#include "JSFunction.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "Interpreter.h" -#include "Lexer.h" -#include "PrototypeFunction.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype); - -static EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*); -static EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*); - -FunctionPrototype::FunctionPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : InternalFunction(&exec->globalData(), globalObject, structure, exec->propertyNames().nullIdentifier) -{ - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); -} - -void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction) -{ - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum); - *applyFunction = new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply); - putDirectFunctionWithoutTransition(exec, *applyFunction, DontEnum); - *callFunction = new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall); - putDirectFunctionWithoutTransition(exec, *callFunction, DontEnum); -} - -static EncodedJSValue JSC_HOST_CALL callFunctionPrototype(ExecState*) -{ - return JSValue::encode(jsUndefined()); -} - -// ECMA 15.3.4 -CallType FunctionPrototype::getCallData(CallData& callData) -{ - callData.native.function = callFunctionPrototype; - return CallTypeHost; -} - -// Functions - -// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.) -static inline void insertSemicolonIfNeeded(UString& functionBody) -{ - ASSERT(functionBody[0] == '{'); - ASSERT(functionBody[functionBody.length() - 1] == '}'); - - for (size_t i = functionBody.length() - 2; i > 0; --i) { - UChar ch = functionBody[i]; - if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) { - if (ch != ';' && ch != '}') - functionBody = makeUString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1))); - return; - } - } -} - -EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.inherits(&JSFunction::info)) { - JSFunction* function = asFunction(thisValue); - if (function->isHostFunction()) - return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); - FunctionExecutable* executable = function->jsExecutable(); - UString sourceString = executable->source().toString(); - insertSemicolonIfNeeded(sourceString); - return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString)); - } - - if (thisValue.inherits(&InternalFunction::info)) { - InternalFunction* function = asInternalFunction(thisValue); - return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); - } - - return throwVMTypeError(exec); -} - -EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - CallData callData; - CallType callType = getCallData(thisValue, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - JSValue array = exec->argument(1); - - MarkedArgumentBuffer applyArgs; - if (!array.isUndefinedOrNull()) { - if (!array.isObject()) - return throwVMTypeError(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(array)->get(exec, i)); - } else - return throwVMTypeError(exec); - } - - return JSValue::encode(call(exec, thisValue, callType, callData, exec->argument(0), applyArgs)); -} - -EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - CallData callData; - CallType callType = getCallData(thisValue, callData); - if (callType == CallTypeNone) - return throwVMTypeError(exec); - - ArgList args(exec); - ArgList callArgs; - args.getSlice(1, callArgs); - return JSValue::encode(call(exec, thisValue, callType, callData, exec->argument(0), callArgs)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/FunctionPrototype.h b/JavaScriptCore/runtime/FunctionPrototype.h deleted file mode 100644 index 5661194..0000000 --- a/JavaScriptCore/runtime/FunctionPrototype.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef FunctionPrototype_h -#define FunctionPrototype_h - -#include "InternalFunction.h" - -namespace JSC { - - class PrototypeFunction; - - class FunctionPrototype : public InternalFunction { - public: - FunctionPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>); - void addFunctionProperties(ExecState*, JSGlobalObject*, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction); - - static PassRefPtr<Structure> createStructure(JSValue proto) - { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - private: - virtual CallType getCallData(CallData&); - }; - -} // namespace JSC - -#endif // FunctionPrototype_h diff --git a/JavaScriptCore/runtime/GCActivityCallback.cpp b/JavaScriptCore/runtime/GCActivityCallback.cpp deleted file mode 100644 index 161abfb..0000000 --- a/JavaScriptCore/runtime/GCActivityCallback.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "GCActivityCallback.h" - -namespace JSC { - -struct DefaultGCActivityCallbackPlatformData { -}; - -DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap) -{ -} - -DefaultGCActivityCallback::~DefaultGCActivityCallback() -{ -} - -void DefaultGCActivityCallback::operator()() -{ -} - -void DefaultGCActivityCallback::synchronize() -{ -} - -} - diff --git a/JavaScriptCore/runtime/GCActivityCallback.h b/JavaScriptCore/runtime/GCActivityCallback.h deleted file mode 100644 index 862b4df..0000000 --- a/JavaScriptCore/runtime/GCActivityCallback.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2010 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 GCActivityCallback_h -#define GCActivityCallback_h - -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> - -namespace JSC { - -class Heap; - -class GCActivityCallback { -public: - virtual ~GCActivityCallback() {} - virtual void operator()() {} - virtual void synchronize() {} - -protected: - GCActivityCallback() {} -}; - -struct DefaultGCActivityCallbackPlatformData; - -class DefaultGCActivityCallback : public GCActivityCallback { -public: - static PassOwnPtr<DefaultGCActivityCallback> create(Heap*); - - DefaultGCActivityCallback(Heap*); - ~DefaultGCActivityCallback(); - - void operator()(); - void synchronize(); - -private: - OwnPtr<DefaultGCActivityCallbackPlatformData*> d; -}; - -inline PassOwnPtr<DefaultGCActivityCallback> DefaultGCActivityCallback::create(Heap* heap) -{ - return adoptPtr(new DefaultGCActivityCallback(heap)); -} - -} - -#endif diff --git a/JavaScriptCore/runtime/GCActivityCallbackCF.cpp b/JavaScriptCore/runtime/GCActivityCallbackCF.cpp deleted file mode 100644 index 7168a05..0000000 --- a/JavaScriptCore/runtime/GCActivityCallbackCF.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "GCActivityCallback.h" - -#include "APIShims.h" -#include "Collector.h" -#include "JSGlobalData.h" -#include "JSLock.h" -#include <wtf/RetainPtr.h> -#include <wtf/WTFThreadData.h> -#include <CoreFoundation/CoreFoundation.h> - -#if !PLATFORM(CF) -#error "This file should only be used on CF platforms." -#endif - -namespace JSC { - -struct DefaultGCActivityCallbackPlatformData { - static void trigger(CFRunLoopTimerRef, void *info); - - RetainPtr<CFRunLoopTimerRef> timer; - RetainPtr<CFRunLoopRef> runLoop; - CFRunLoopTimerContext context; -}; - -const CFTimeInterval decade = 60 * 60 * 24 * 365 * 10; -const CFTimeInterval triggerInterval = 2; // seconds - -void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef, void *info) -{ - Heap* heap = static_cast<Heap*>(info); - APIEntryShim shim(heap->globalData()); - heap->collectAllGarbage(); -} - -DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap) -{ - d = adoptPtr(new DefaultGCActivityCallbackPlatformData); - - memset(&d->context, '\0', sizeof(CFRunLoopTimerContext)); - d->context.info = heap; - d->runLoop = CFRunLoopGetCurrent(); - d->timer.adoptCF(CFRunLoopTimerCreate(0, decade, decade, 0, 0, DefaultGCActivityCallbackPlatformData::trigger, &d->context)); - CFRunLoopAddTimer(d->runLoop.get(), d->timer.get(), kCFRunLoopCommonModes); -} - -DefaultGCActivityCallback::~DefaultGCActivityCallback() -{ - CFRunLoopRemoveTimer(d->runLoop.get(), d->timer.get(), kCFRunLoopCommonModes); - CFRunLoopTimerInvalidate(d->timer.get()); - d->context.info = 0; - d->runLoop = 0; - d->timer = 0; -} - -void DefaultGCActivityCallback::operator()() -{ - CFRunLoopTimerSetNextFireDate(d->timer.get(), CFAbsoluteTimeGetCurrent() + triggerInterval); -} - -void DefaultGCActivityCallback::synchronize() -{ - if (CFRunLoopGetCurrent() == d->runLoop.get()) - return; - CFRunLoopRemoveTimer(d->runLoop.get(), d->timer.get(), kCFRunLoopCommonModes); - d->runLoop = CFRunLoopGetCurrent(); - CFRunLoopAddTimer(d->runLoop.get(), d->timer.get(), kCFRunLoopCommonModes); -} - -} diff --git a/JavaScriptCore/runtime/GCHandle.cpp b/JavaScriptCore/runtime/GCHandle.cpp deleted file mode 100644 index 297de38..0000000 --- a/JavaScriptCore/runtime/GCHandle.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 "GCHandle.h" - -namespace JSC { - -WeakGCHandlePool* WeakGCHandle::pool() -{ - uintptr_t pool = (reinterpret_cast<uintptr_t>(this) & WeakGCHandlePool::poolMask); - return reinterpret_cast<WeakGCHandlePool*>(pool); -} - -WeakGCHandlePool::WeakGCHandlePool() -{ - ASSERT(sizeof(WeakGCHandlePool) <= WeakGCHandlePool::poolSize); - m_entriesSize = 0; - m_initialAlloc = 1; - m_entries[0].setNextInFreeList(0); -} - -WeakGCHandle* WeakGCHandlePool::allocate(JSCell* cell) -{ - ASSERT(cell); - ASSERT(m_entries[0].isNext()); - unsigned freeList = m_entries[0].getNextInFreeList(); - ASSERT(freeList < WeakGCHandlePool::numPoolEntries); - ASSERT(m_entriesSize < WeakGCHandlePool::numPoolEntries); - - if (m_entriesSize == WeakGCHandlePool::numPoolEntries - 1) - return 0; - - if (freeList) { - unsigned i = freeList; - freeList = m_entries[i].getNextInFreeList(); - m_entries[i].set(cell); - m_entries[0].setNextInFreeList(freeList); - ++m_entriesSize; - return &m_entries[i]; - } - - ASSERT(m_initialAlloc < WeakGCHandlePool::numPoolEntries); - - unsigned i = m_initialAlloc; - ++m_initialAlloc; - m_entries[i].set(cell); - ++m_entriesSize; - return &m_entries[i]; - -} - -void WeakGCHandlePool::free(WeakGCHandle* handle) -{ - ASSERT(handle->pool() == this); - ASSERT(m_entries[0].isNext()); - unsigned freeList = m_entries[0].getNextInFreeList(); - ASSERT(freeList < WeakGCHandlePool::numPoolEntries); - handle->setNextInFreeList(freeList); - m_entries[0].setNextInFreeList(handle - m_entries); - --m_entriesSize; -} - -} diff --git a/JavaScriptCore/runtime/GCHandle.h b/JavaScriptCore/runtime/GCHandle.h deleted file mode 100644 index 8818f79..0000000 --- a/JavaScriptCore/runtime/GCHandle.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 GCHandle_h -#define GCHandle_h - -#include <wtf/Assertions.h> - -namespace JSC { - -class Heap; -class JSCell; -class WeakGCHandle; -class WeakGCHandlePool; - -class WeakGCHandle { - friend class WeakGCHandlePool; - -public: - // Because JSCell objects are aligned, we can use the lower two bits as - // status flags. The least significant bit is set when the handle is not a - // pointer, i.e. when it's used as a offset for the free list in - // WeakGCHandlePool. The second least significant bit is set when the object - // the pointer corresponds to has been deleted by a garbage collection - - bool isValidPtr() { return !(m_ptr & 3); } - bool isPtr() { return !(m_ptr & 1); } - bool isNext() { return (m_ptr & 3) == 1; } - - void invalidate() - { - ASSERT(isValidPtr()); - m_ptr |= 2; - } - - JSCell* get() - { - ASSERT(isPtr()); - return reinterpret_cast<JSCell*>(m_ptr & ~3); - } - - void set(JSCell* p) - { - m_ptr = reinterpret_cast<uintptr_t>(p); - ASSERT(isPtr()); - } - - WeakGCHandlePool* pool(); - -private: - uintptr_t getNextInFreeList() - { - ASSERT(isNext()); - return m_ptr >> 2; - } - - void setNextInFreeList(uintptr_t n) - { - m_ptr = (n << 2) | 1; - ASSERT(isNext()); - } - - uintptr_t m_ptr; -}; - -class WeakGCHandlePool { -public: - static const size_t poolSize = 32 * 1024; // 32k - static const size_t poolMask = ~(poolSize - 1); - static const size_t numPoolEntries = (poolSize - sizeof(Heap*) - 3 * sizeof(unsigned)) / sizeof(WeakGCHandle); - - WeakGCHandlePool(); - - WeakGCHandle* allocate(JSCell* cell); - void free(WeakGCHandle*); - - bool isFull() - { - ASSERT(m_entriesSize < WeakGCHandlePool::numPoolEntries); - return m_entriesSize == WeakGCHandlePool::numPoolEntries - 1; - } - - void update(); - -private: - Heap* m_heap; - unsigned m_entriesSize; - unsigned m_initialAlloc; - - WeakGCHandle m_entries[WeakGCHandlePool::numPoolEntries]; -}; - -} -#endif diff --git a/JavaScriptCore/runtime/GetterSetter.cpp b/JavaScriptCore/runtime/GetterSetter.cpp deleted file mode 100644 index 7e54053..0000000 --- a/JavaScriptCore/runtime/GetterSetter.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "GetterSetter.h" - -#include "JSObject.h" -#include <wtf/Assertions.h> - -namespace JSC { - -void GetterSetter::markChildren(MarkStack& markStack) -{ - JSCell::markChildren(markStack); - - if (m_getter) - markStack.append(m_getter); - if (m_setter) - markStack.append(m_setter); -} - -bool GetterSetter::isGetterSetter() const -{ - return true; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/GetterSetter.h b/JavaScriptCore/runtime/GetterSetter.h deleted file mode 100644 index e7b1938..0000000 --- a/JavaScriptCore/runtime/GetterSetter.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef GetterSetter_h -#define GetterSetter_h - -#include "JSCell.h" - -#include "CallFrame.h" - -namespace JSC { - - class JSObject; - - // This is an internal value object which stores getter and setter functions - // for a property. - class GetterSetter : public JSCell { - friend class JIT; - public: - GetterSetter(ExecState* exec) - : JSCell(exec->globalData().getterSetterStructure.get()) - , m_getter(0) - , m_setter(0) - { - } - - virtual void markChildren(MarkStack&); - - JSObject* getter() const { return m_getter; } - void setGetter(JSObject* getter) { m_getter = getter; } - JSObject* setter() const { return m_setter; } - void setSetter(JSObject* setter) { m_setter = setter; } - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount); - } - private: - virtual bool isGetterSetter() const; - - JSObject* m_getter; - JSObject* m_setter; - }; - - GetterSetter* asGetterSetter(JSValue); - - inline GetterSetter* asGetterSetter(JSValue value) - { - ASSERT(value.asCell()->isGetterSetter()); - return static_cast<GetterSetter*>(value.asCell()); - } - - -} // namespace JSC - -#endif // GetterSetter_h diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/JavaScriptCore/runtime/GlobalEvalFunction.cpp deleted file mode 100644 index 3ad4644..0000000 --- a/JavaScriptCore/runtime/GlobalEvalFunction.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "GlobalEvalFunction.h" - -#include "JSGlobalObject.h" -#include <wtf/Assertions.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction); - -GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject) - : PrototypeFunction(exec, globalObject, structure, len, name, function) - , m_cachedGlobalObject(cachedGlobalObject) -{ - ASSERT_ARG(cachedGlobalObject, cachedGlobalObject); -} - -void GlobalEvalFunction::markChildren(MarkStack& markStack) -{ - PrototypeFunction::markChildren(markStack); - markStack.append(m_cachedGlobalObject); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.h b/JavaScriptCore/runtime/GlobalEvalFunction.h deleted file mode 100644 index b889ca9..0000000 --- a/JavaScriptCore/runtime/GlobalEvalFunction.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef GlobalEvalFunction_h -#define GlobalEvalFunction_h - -#include "PrototypeFunction.h" - -namespace JSC { - - class JSGlobalObject; - - class GlobalEvalFunction : public PrototypeFunction { - public: - GlobalEvalFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject); - JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | PrototypeFunction::StructureFlags; - - private: - virtual void markChildren(MarkStack&); - - JSGlobalObject* m_cachedGlobalObject; - }; - -} // namespace JSC - -#endif // GlobalEvalFunction_h diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp deleted file mode 100644 index 28cfd0a..0000000 --- a/JavaScriptCore/runtime/Identifier.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "Identifier.h" - -#include "CallFrame.h" -#include "NumericStrings.h" -#include <new> // for placement new -#include <string.h> // for strlen -#include <wtf/Assertions.h> -#include <wtf/FastMalloc.h> -#include <wtf/HashSet.h> -#include <wtf/WTFThreadData.h> -#include <wtf/text/StringHash.h> - -using WTF::ThreadSpecific; - -namespace JSC { - -IdentifierTable::~IdentifierTable() -{ - HashSet<StringImpl*>::iterator end = m_table.end(); - for (HashSet<StringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter) - (*iter)->setIsIdentifier(false); -} -std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value) -{ - std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value); - (*result.first)->setIsIdentifier(true); - return result; -} -template<typename U, typename V> -std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(U value) -{ - std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add<U, V>(value); - (*result.first)->setIsIdentifier(true); - return result; -} - -IdentifierTable* createIdentifierTable() -{ - return new IdentifierTable; -} - -void deleteIdentifierTable(IdentifierTable* table) -{ - delete table; -} - -bool Identifier::equal(const StringImpl* r, const char* s) -{ - int length = r->length(); - const UChar* d = r->characters(); - for (int i = 0; i != length; ++i) - if (d[i] != (unsigned char)s[i]) - return false; - return s[length] == 0; -} - -bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length) -{ - if (r->length() != length) - return false; - const UChar* d = r->characters(); - for (unsigned i = 0; i != length; ++i) - if (d[i] != s[i]) - return false; - return true; -} - -struct IdentifierCStringTranslator { - static unsigned hash(const char* c) - { - return WTF::StringHasher::createHash<char>(c); - } - - static bool equal(StringImpl* r, const char* s) - { - return Identifier::equal(r, s); - } - - static void translate(StringImpl*& location, const char* c, unsigned hash) - { - size_t length = strlen(c); - UChar* d; - StringImpl* r = StringImpl::createUninitialized(length, d).leakRef(); - 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 - r->setHash(hash); - location = r; - } -}; - -PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c) -{ - if (!c) - return 0; - if (!c[0]) - return StringImpl::empty(); - if (!c[1]) - return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0]))); - - IdentifierTable& identifierTable = *globalData->identifierTable; - LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable(); - - const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c); - if (iter != literalIdentifierTable.end()) - return iter->second; - - pair<HashSet<StringImpl*>::iterator, bool> addResult = identifierTable.add<const char*, IdentifierCStringTranslator>(c); - - // If the string is newly-translated, then we need to adopt it. - // The boolean in the pair tells us if that is so. - RefPtr<StringImpl> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first; - - literalIdentifierTable.add(c, addedString.get()); - - return addedString.release(); -} - -PassRefPtr<StringImpl> Identifier::add(ExecState* exec, const char* c) -{ - return add(&exec->globalData(), c); -} - -struct UCharBuffer { - const UChar* s; - unsigned int length; -}; - -struct IdentifierUCharBufferTranslator { - static unsigned hash(const UCharBuffer& buf) - { - return WTF::StringHasher::createHash<UChar>(buf.s, buf.length); - } - - static bool equal(StringImpl* str, const UCharBuffer& buf) - { - return Identifier::equal(str, buf.s, buf.length); - } - - static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) - { - UChar* d; - StringImpl* r = StringImpl::createUninitialized(buf.length, d).leakRef(); - for (unsigned i = 0; i != buf.length; i++) - d[i] = buf.s[i]; - r->setHash(hash); - location = r; - } -}; - -uint32_t Identifier::toUInt32(const UString& string, bool& ok) -{ - ok = false; - - unsigned length = string.length(); - const UChar* characters = string.characters(); - - // An empty string is not a number. - if (!length) - return 0; - - // Get the first character, turning it into a digit. - uint32_t value = characters[0] - '0'; - if (value > 9) - return 0; - - // Check for leading zeros. If the first characher is 0, then the - // length of the string must be one - e.g. "042" is not equal to "42". - if (!value && length > 1) - return 0; - - while (--length) { - // Multiply value by 10, checking for overflow out of 32 bits. - if (value > 0xFFFFFFFFU / 10) - return 0; - value *= 10; - - // Get the next character, turning it into a digit. - uint32_t newValue = *(++characters) - '0'; - if (newValue > 9) - return 0; - - // Add in the old value, checking for overflow out of 32 bits. - newValue += value; - if (newValue < value) - return 0; - value = newValue; - } - - ok = true; - return value; -} - -PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const UChar* s, int length) -{ - if (length == 1) { - UChar c = s[0]; - if (c <= 0xFF) - return add(globalData, globalData->smallStrings.singleCharacterStringRep(c)); - } - if (!length) - return StringImpl::empty(); - UCharBuffer buf = {s, length}; - pair<HashSet<StringImpl*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf); - - // If the string is newly-translated, then we need to adopt it. - // The boolean in the pair tells us if that is so. - return addResult.second ? adoptRef(*addResult.first) : *addResult.first; -} - -PassRefPtr<StringImpl> Identifier::add(ExecState* exec, const UChar* s, int length) -{ - return add(&exec->globalData(), s, length); -} - -PassRefPtr<StringImpl> Identifier::addSlowCase(JSGlobalData* globalData, StringImpl* r) -{ - ASSERT(!r->isIdentifier()); - // The empty & null strings are static singletons, and static strings are handled - // in ::add() in the header, so we should never get here with a zero length string. - ASSERT(r->length()); - - if (r->length() == 1) { - UChar c = r->characters()[0]; - if (c <= 0xFF) - r = globalData->smallStrings.singleCharacterStringRep(c); - if (r->isIdentifier()) - return r; - } - - return *globalData->identifierTable->add(r).first; -} - -PassRefPtr<StringImpl> Identifier::addSlowCase(ExecState* exec, StringImpl* r) -{ - return addSlowCase(&exec->globalData(), r); -} - -Identifier Identifier::from(ExecState* exec, unsigned value) -{ - return Identifier(exec, exec->globalData().numericStrings.add(value)); -} - -Identifier Identifier::from(ExecState* exec, int value) -{ - return Identifier(exec, exec->globalData().numericStrings.add(value)); -} - -Identifier Identifier::from(ExecState* exec, double value) -{ - return Identifier(exec, exec->globalData().numericStrings.add(value)); -} - -Identifier Identifier::from(JSGlobalData* globalData, unsigned value) -{ - return Identifier(globalData, globalData->numericStrings.add(value)); -} - -Identifier Identifier::from(JSGlobalData* globalData, int value) -{ - return Identifier(globalData, globalData->numericStrings.add(value)); -} - -Identifier Identifier::from(JSGlobalData* globalData, double value) -{ - return Identifier(globalData, globalData->numericStrings.add(value)); -} - -#ifndef NDEBUG - -void Identifier::checkCurrentIdentifierTable(JSGlobalData* globalData) -{ - // Check the identifier table accessible through the threadspecific matches the - // globalData's identifier table. - ASSERT_UNUSED(globalData, globalData->identifierTable == wtfThreadData().currentIdentifierTable()); -} - -void Identifier::checkCurrentIdentifierTable(ExecState* exec) -{ - checkCurrentIdentifierTable(&exec->globalData()); -} - -#else - -// These only exists so that our exports are the same for debug and release builds. -// This would be an ASSERT_NOT_REACHED(), but we're in NDEBUG only code here! -void Identifier::checkCurrentIdentifierTable(JSGlobalData*) { CRASH(); } -void Identifier::checkCurrentIdentifierTable(ExecState*) { CRASH(); } - -#endif - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Identifier.h b/JavaScriptCore/runtime/Identifier.h deleted file mode 100644 index 3a8aed7..0000000 --- a/JavaScriptCore/runtime/Identifier.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Identifier_h -#define Identifier_h - -#include "JSGlobalData.h" -#include "ThreadSpecific.h" -#include "UString.h" -#include <wtf/text/CString.h> - -namespace JSC { - - class ExecState; - - class Identifier { - friend class Structure; - public: - Identifier() { } - - Identifier(ExecState* exec, const char* s) : m_string(add(exec, s)) { } // Only to be used with string literals. - Identifier(ExecState* exec, const UChar* s, int length) : m_string(add(exec, s, length)) { } - Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { } - Identifier(ExecState* exec, const UString& s) : m_string(add(exec, s.impl())) { } - - Identifier(JSGlobalData* globalData, const char* s) : m_string(add(globalData, s)) { } // Only to be used with string literals. - Identifier(JSGlobalData* globalData, const UChar* s, int length) : m_string(add(globalData, s, length)) { } - Identifier(JSGlobalData* globalData, StringImpl* rep) : m_string(add(globalData, rep)) { } - Identifier(JSGlobalData* globalData, const UString& s) : m_string(add(globalData, s.impl())) { } - - const UString& ustring() const { return m_string; } - StringImpl* impl() const { return m_string.impl(); } - - const UChar* characters() const { return m_string.characters(); } - int length() const { return m_string.length(); } - - CString ascii() const { return m_string.ascii(); } - - static Identifier from(ExecState* exec, unsigned y); - static Identifier from(ExecState* exec, int y); - static Identifier from(ExecState* exec, double y); - static Identifier from(JSGlobalData*, unsigned y); - static Identifier from(JSGlobalData*, int y); - static Identifier from(JSGlobalData*, double y); - - static uint32_t toUInt32(const UString&, bool& ok); - uint32_t toUInt32(bool& ok) const { return toUInt32(m_string, ok); } - unsigned toArrayIndex(bool& ok) const; - - bool isNull() const { return m_string.isNull(); } - bool isEmpty() const { return m_string.isEmpty(); } - - friend bool operator==(const Identifier&, const Identifier&); - friend bool operator!=(const Identifier&, const Identifier&); - - friend bool operator==(const Identifier&, const char*); - friend bool operator!=(const Identifier&, const char*); - - static bool equal(const StringImpl*, const char*); - static bool equal(const StringImpl*, const UChar*, unsigned length); - static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); } - - static PassRefPtr<StringImpl> add(ExecState*, const char*); // Only to be used with string literals. - static PassRefPtr<StringImpl> add(JSGlobalData*, const char*); // Only to be used with string literals. - - private: - UString m_string; - - static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); } - static bool equal(const Identifier& a, const char* b) { return equal(a.m_string.impl(), b); } - - static PassRefPtr<StringImpl> add(ExecState*, const UChar*, int length); - static PassRefPtr<StringImpl> add(JSGlobalData*, const UChar*, int length); - - static PassRefPtr<StringImpl> add(ExecState* exec, StringImpl* r) - { -#ifndef NDEBUG - checkCurrentIdentifierTable(exec); -#endif - if (r->isIdentifier()) - return r; - return addSlowCase(exec, r); - } - static PassRefPtr<StringImpl> add(JSGlobalData* globalData, StringImpl* r) - { -#ifndef NDEBUG - checkCurrentIdentifierTable(globalData); -#endif - if (r->isIdentifier()) - return r; - return addSlowCase(globalData, r); - } - - static PassRefPtr<StringImpl> addSlowCase(ExecState*, StringImpl* r); - static PassRefPtr<StringImpl> addSlowCase(JSGlobalData*, StringImpl* r); - - static void checkCurrentIdentifierTable(ExecState*); - static void checkCurrentIdentifierTable(JSGlobalData*); - }; - - inline bool operator==(const Identifier& a, const Identifier& b) - { - return Identifier::equal(a, b); - } - - inline bool operator!=(const Identifier& a, const Identifier& b) - { - return !Identifier::equal(a, b); - } - - inline bool operator==(const Identifier& a, const char* b) - { - return Identifier::equal(a, b); - } - - inline bool operator!=(const Identifier& a, const char* b) - { - return !Identifier::equal(a, b); - } - - IdentifierTable* createIdentifierTable(); - void deleteIdentifierTable(IdentifierTable*); - - struct IdentifierRepHash : PtrHash<RefPtr<StringImpl> > { - static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); } - static unsigned hash(StringImpl* key) { return key->existingHash(); } - }; - -} // namespace JSC - -#endif // Identifier_h diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp deleted file mode 100644 index 08dddc1..0000000 --- a/JavaScriptCore/runtime/InitializeThreading.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "InitializeThreading.h" - -#include "Collector.h" -#include "dtoa.h" -#include "Identifier.h" -#include "JSGlobalObject.h" -#include "UString.h" -#include <wtf/DateMath.h> -#include <wtf/Threading.h> -#include <wtf/WTFThreadData.h> - -using namespace WTF; - -namespace JSC { - -#if OS(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS) -static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT; -#endif - -static void initializeThreadingOnce() -{ - // StringImpl::empty() does not construct its static string in a threadsafe fashion, - // so ensure it has been initialized from here. - StringImpl::empty(); - - WTF::initializeThreading(); - wtfThreadData(); - JSGlobalData::storeVPtrs(); -#if ENABLE(JSC_MULTIPLE_THREADS) - s_dtoaP5Mutex = new Mutex; - initializeDates(); - RegisterFile::initializeThreading(); -#endif -} - -void initializeThreading() -{ -#if OS(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS) - pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce); -#else - static bool initializedThreading = false; - if (!initializedThreading) { - initializeThreadingOnce(); - initializedThreading = true; - } -#endif -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/InitializeThreading.h b/JavaScriptCore/runtime/InitializeThreading.h deleted file mode 100644 index 1a93ccb..0000000 --- a/JavaScriptCore/runtime/InitializeThreading.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InitializeThreading_h -#define InitializeThreading_h - -namespace JSC { - - // This function must be called from the main thread. It is safe to call it repeatedly. - // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly. - void initializeThreading(); - -} - -#endif // InitializeThreading_h diff --git a/JavaScriptCore/runtime/InternalFunction.cpp b/JavaScriptCore/runtime/InternalFunction.cpp deleted file mode 100644 index 0a8d9de..0000000 --- a/JavaScriptCore/runtime/InternalFunction.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "InternalFunction.h" - -#include "FunctionPrototype.h" -#include "JSGlobalObject.h" -#include "JSString.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(InternalFunction); - -const ClassInfo InternalFunction::info = { "Function", 0, 0, 0 }; - -const ClassInfo* InternalFunction::classInfo() const -{ - return &info; -} - -InternalFunction::InternalFunction(NonNullPassRefPtr<Structure> structure) - : JSObjectWithGlobalObject(structure) -{ -} - -InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const Identifier& name) - : JSObjectWithGlobalObject(globalObject, structure) -{ - putDirect(globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); -} - -const UString& InternalFunction::name(ExecState* exec) -{ - return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue(); -} - -const UString InternalFunction::displayName(ExecState* exec) -{ - JSValue displayName = getDirect(exec->globalData().propertyNames->displayName); - - if (displayName && isJSString(&exec->globalData(), displayName)) - return asString(displayName)->tryGetValue(); - - return UString(); -} - -const UString InternalFunction::calculatedDisplayName(ExecState* exec) -{ - const UString explicitName = displayName(exec); - - if (!explicitName.isEmpty()) - return explicitName; - - return name(exec); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/InternalFunction.h b/JavaScriptCore/runtime/InternalFunction.h deleted file mode 100644 index 401f17b..0000000 --- a/JavaScriptCore/runtime/InternalFunction.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef InternalFunction_h -#define InternalFunction_h - -#include "JSObjectWithGlobalObject.h" -#include "Identifier.h" - -namespace JSC { - - class FunctionPrototype; - - class InternalFunction : public JSObjectWithGlobalObject { - public: - virtual const ClassInfo* classInfo() const; - static JS_EXPORTDATA const ClassInfo info; - - const UString& name(ExecState*); - const UString displayName(ExecState*); - const UString calculatedDisplayName(ExecState*); - - static PassRefPtr<Structure> createStructure(JSValue proto) - { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; - - // Only used to allow us to determine the JSFunction vptr - InternalFunction(NonNullPassRefPtr<Structure> structure); - - InternalFunction(JSGlobalData*, JSGlobalObject*, NonNullPassRefPtr<Structure>, const Identifier&); - - private: - virtual CallType getCallData(CallData&) = 0; - }; - - InternalFunction* asInternalFunction(JSValue); - - inline InternalFunction* asInternalFunction(JSValue value) - { - ASSERT(asObject(value)->inherits(&InternalFunction::info)); - return static_cast<InternalFunction*>(asObject(value)); - } - -} // namespace JSC - -#endif // InternalFunction_h diff --git a/JavaScriptCore/runtime/JSAPIValueWrapper.cpp b/JavaScriptCore/runtime/JSAPIValueWrapper.cpp deleted file mode 100644 index e83724a..0000000 --- a/JavaScriptCore/runtime/JSAPIValueWrapper.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSAPIValueWrapper.h" - -#include "NumberObject.h" -#include "UString.h" - -namespace JSC { - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSAPIValueWrapper.h b/JavaScriptCore/runtime/JSAPIValueWrapper.h deleted file mode 100644 index 10ded4c..0000000 --- a/JavaScriptCore/runtime/JSAPIValueWrapper.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSAPIValueWrapper_h -#define JSAPIValueWrapper_h - -#include "JSCell.h" -#include "CallFrame.h" - -namespace JSC { - - class JSAPIValueWrapper : public JSCell { - friend JSValue jsAPIValueWrapper(ExecState*, JSValue); - public: - JSValue value() const { return m_value; } - - virtual bool isAPIValueWrapper() const { return true; } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount); - } - - - private: - JSAPIValueWrapper(ExecState* exec, JSValue value) - : JSCell(exec->globalData().apiWrapperStructure.get()) - , m_value(value) - { - ASSERT(!value.isCell()); - } - - JSValue m_value; - }; - - inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value) - { - return new (exec) JSAPIValueWrapper(exec, value); - } - -} // namespace JSC - -#endif // JSAPIValueWrapper_h diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp deleted file mode 100644 index 1147858..0000000 --- a/JavaScriptCore/runtime/JSActivation.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "JSActivation.h" - -#include "Arguments.h" -#include "Interpreter.h" -#include "JSFunction.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSActivation); - -const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 }; - -JSActivation::JSActivation(CallFrame* callFrame, NonNullPassRefPtr<FunctionExecutable> functionExecutable) - : Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers())) -{ -} - -JSActivation::~JSActivation() -{ - delete d(); -} - -void JSActivation::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - - Register* registerArray = d()->registerArray.get(); - if (!registerArray) - return; - - size_t numParametersMinusThis = d()->functionExecutable->parameterCount(); - - size_t count = numParametersMinusThis; - markStack.appendValues(registerArray, count); - - size_t numVars = d()->functionExecutable->capturedVariableCount(); - - // Skip the call frame, which sits between the parameters and vars. - markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues); -} - -inline bool JSActivation::symbolTableGet(const Identifier& propertyName, PropertySlot& slot) -{ - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); - if (!entry.isNull()) { - ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount())); - slot.setRegisterSlot(®isterAt(entry.getIndex())); - return true; - } - return false; -} - -inline bool JSActivation::symbolTablePut(const Identifier& propertyName, JSValue value) -{ - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); - if (entry.isNull()) - return false; - if (entry.isReadOnly()) - return true; - ASSERT(entry.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount())); - registerAt(entry.getIndex()) = value; - return true; -} - -void JSActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - SymbolTable::const_iterator end = symbolTable().end(); - for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) { - ASSERT(it->second.getIndex() < static_cast<int>(d()->functionExecutable->capturedVariableCount())); - if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties)) - propertyNames.add(Identifier(exec, it->first.get())); - } - // Skip the JSVariableObject implementation of getOwnPropertyNames - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -inline bool JSActivation::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes) -{ - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - SymbolTable::iterator iter = symbolTable().find(propertyName.impl()); - if (iter == symbolTable().end()) - return false; - SymbolTableEntry& entry = iter->second; - ASSERT(!entry.isNull()); - if (entry.getIndex() >= static_cast<int>(d()->functionExecutable->capturedVariableCount())) - return false; - entry.setAttributes(attributes); - registerAt(entry.getIndex()) = value; - return true; -} - -bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (propertyName == exec->propertyNames().arguments) { - slot.setCustom(this, getArgumentsGetter()); - return true; - } - - if (symbolTableGet(propertyName, slot)) - return true; - - if (JSValue* location = getDirectLocation(propertyName)) { - slot.setValueSlot(location); - return true; - } - - // We don't call through to JSObject because there's no way to give an - // activation object getter properties or a prototype. - ASSERT(!hasGetterSetterProperties()); - ASSERT(prototype().isNull()); - return false; -} - -void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - if (symbolTablePut(propertyName, value)) - return; - - // We don't call through to JSObject because __proto__ and getter/setter - // properties are non-standard extensions that other implementations do not - // expose in the activation object. - ASSERT(!hasGetterSetterProperties()); - putDirect(propertyName, value, 0, true, slot); -} - -// FIXME: Make this function honor ReadOnly (const) and DontEnum -void JSActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) -{ - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - if (symbolTablePutWithAttributes(propertyName, value, attributes)) - return; - - // We don't call through to JSObject because __proto__ and getter/setter - // properties are non-standard extensions that other implementations do not - // expose in the activation object. - ASSERT(!hasGetterSetterProperties()); - PutPropertySlot slot; - JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot); -} - -bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - if (propertyName == exec->propertyNames().arguments) - return false; - - return Base::deleteProperty(exec, propertyName); -} - -JSObject* JSActivation::toThisObject(ExecState* exec) const -{ - return exec->globalThisValue(); -} - -JSValue JSActivation::toStrictThisObject(ExecState*) const -{ - return jsNull(); -} - -bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const -{ - requiresDynamicChecks = d()->functionExecutable->usesEval(); - return false; -} - -JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identifier&) -{ - JSActivation* activation = asActivation(slotBase); - CallFrame* callFrame = CallFrame::create(activation->d()->registers); - int argumentsRegister = activation->d()->functionExecutable->generatedBytecode().argumentsRegister(); - if (!callFrame->uncheckedR(argumentsRegister).jsValue()) { - JSValue arguments = JSValue(new (callFrame) Arguments(callFrame)); - callFrame->uncheckedR(argumentsRegister) = arguments; - callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = arguments; - } - - ASSERT(callFrame->uncheckedR(argumentsRegister).jsValue().inherits(&Arguments::info)); - return callFrame->uncheckedR(argumentsRegister).jsValue(); -} - -// These two functions serve the purpose of isolating the common case from a -// PIC branch. - -PropertySlot::GetValueFunc JSActivation::getArgumentsGetter() -{ - return argumentsGetter; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h deleted file mode 100644 index 6dd6d70..0000000 --- a/JavaScriptCore/runtime/JSActivation.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSActivation_h -#define JSActivation_h - -#include "CodeBlock.h" -#include "JSVariableObject.h" -#include "SymbolTable.h" -#include "Nodes.h" - -namespace JSC { - - class Arguments; - class Register; - - class JSActivation : public JSVariableObject { - typedef JSVariableObject Base; - public: - JSActivation(CallFrame*, NonNullPassRefPtr<FunctionExecutable>); - virtual ~JSActivation(); - - virtual void markChildren(MarkStack&); - - virtual bool isDynamicScope(bool& requiresDynamicChecks) const; - - virtual bool isActivationObject() const { return true; } - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode); - - virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); - - virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - - virtual JSObject* toThisObject(ExecState*) const; - virtual JSValue toStrictThisObject(ExecState*) const; - - void copyRegisters(); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; - - private: - struct JSActivationData : public JSVariableObjectData { - JSActivationData(NonNullPassRefPtr<FunctionExecutable> _functionExecutable, Register* registers) - : JSVariableObjectData(_functionExecutable->symbolTable(), registers) - , functionExecutable(_functionExecutable) - { - // We have to manually ref and deref the symbol table as JSVariableObjectData - // doesn't know about SharedSymbolTable - functionExecutable->symbolTable()->ref(); - } - ~JSActivationData() - { - static_cast<SharedSymbolTable*>(symbolTable)->deref(); - } - - RefPtr<FunctionExecutable> functionExecutable; - }; - - bool symbolTableGet(const Identifier&, PropertySlot&); - bool symbolTableGet(const Identifier&, PropertyDescriptor&); - bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); - bool symbolTablePut(const Identifier&, JSValue); - bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes); - - static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&); - NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter(); - - JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); } - }; - - JSActivation* asActivation(JSValue); - - inline JSActivation* asActivation(JSValue value) - { - ASSERT(asObject(value)->inherits(&JSActivation::info)); - return static_cast<JSActivation*>(asObject(value)); - } - -} // namespace JSC - -#endif // JSActivation_h diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp deleted file mode 100644 index 556a16e..0000000 --- a/JavaScriptCore/runtime/JSArray.cpp +++ /dev/null @@ -1,1322 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2003 Peter Kelly (pmk@post.com) - * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "JSArray.h" - -#include "ArrayPrototype.h" -#include "CachedCall.h" -#include "Error.h" -#include "Executable.h" -#include "PropertyNameArray.h" -#include <wtf/AVLTree.h> -#include <wtf/Assertions.h> -#include <wtf/OwnPtr.h> -#include <Operations.h> - -using namespace std; -using namespace WTF; - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSArray); - -// Overview of JSArray -// -// Properties of JSArray objects may be stored in one of three locations: -// * The regular JSObject property map. -// * A storage vector. -// * A sparse map of array entries. -// -// Properties with non-numeric identifiers, with identifiers that are not representable -// as an unsigned integer, or where the value is greater than MAX_ARRAY_INDEX -// (specifically, this is only one property - the value 0xFFFFFFFFU as an unsigned 32-bit -// integer) are not considered array indices and will be stored in the JSObject property map. -// -// All properties with a numeric identifer, representable as an unsigned integer i, -// where (i <= MAX_ARRAY_INDEX), are an array index and will be stored in either the -// storage vector or the sparse map. An array index i will be handled in the following -// fashion: -// -// * Where (i < MIN_SPARSE_ARRAY_INDEX) the value will be stored in the storage vector. -// * Where (MIN_SPARSE_ARRAY_INDEX <= i <= MAX_STORAGE_VECTOR_INDEX) the value will either -// be stored in the storage vector or in the sparse array, depending on the density of -// data that would be stored in the vector (a vector being used where at least -// (1 / minDensityMultiplier) of the entries would be populated). -// * Where (MAX_STORAGE_VECTOR_INDEX < i <= MAX_ARRAY_INDEX) the value will always be stored -// in the sparse array. - -// The definition of MAX_STORAGE_VECTOR_LENGTH is dependant on the definition storageSize -// function below - the MAX_STORAGE_VECTOR_LENGTH limit is defined such that the storage -// size calculation cannot overflow. (sizeof(ArrayStorage) - sizeof(JSValue)) + -// (vectorLength * sizeof(JSValue)) must be <= 0xFFFFFFFFU (which is maximum value of size_t). -#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValue))) / sizeof(JSValue)) - -// These values have to be macros to be used in max() and min() without introducing -// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>. -#define MIN_SPARSE_ARRAY_INDEX 10000U -#define MAX_STORAGE_VECTOR_INDEX (MAX_STORAGE_VECTOR_LENGTH - 1) -// 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer. -#define MAX_ARRAY_INDEX 0xFFFFFFFEU - -// The value BASE_VECTOR_LEN is the maximum number of vector elements we'll allocate -// for an array that was created with a sepcified length (e.g. a = new Array(123)) -#define BASE_VECTOR_LEN 4U - -// The upper bound to the size we'll grow a zero length array when the first element -// is added. -#define FIRST_VECTOR_GROW 4U - -// Our policy for when to use a vector and when to use a sparse map. -// For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector. -// When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector -// as long as it is 1/8 full. If more sparse than that, we use a map. -static const unsigned minDensityMultiplier = 8; - -const ClassInfo JSArray::info = {"Array", 0, 0, 0}; - -// We keep track of the size of the last array after it was grown. We use this -// as a simple heuristic for as the value to grow the next array from size 0. -// This value is capped by the constant FIRST_VECTOR_GROW defined above. -static unsigned lastArraySize = 0; - -static inline size_t storageSize(unsigned vectorLength) -{ - ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH); - - // MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH) - // - as asserted above - the following calculation cannot overflow. - size_t size = (sizeof(ArrayStorage) - sizeof(JSValue)) + (vectorLength * sizeof(JSValue)); - // Assertion to detect integer overflow in previous calculation (should not be possible, provided that - // MAX_STORAGE_VECTOR_LENGTH is correctly defined). - ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValue))) / sizeof(JSValue) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValue)))); - - return size; -} - -static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) -{ - return length / minDensityMultiplier <= numValues; -} - -#if !CHECK_ARRAY_CONSISTENCY - -inline void JSArray::checkConsistency(ConsistencyCheckType) -{ -} - -#endif - -JSArray::JSArray(VPtrStealingHackType) - : JSObject(createStructure(jsNull())) -{ - unsigned initialCapacity = 0; - - m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_storage->m_allocBase = m_storage; - m_indexBias = 0; - m_vectorLength = initialCapacity; - - checkConsistency(); - - // It's not safe to call Heap::heap(this) in order to report extra memory - // cost here, because the VPtrStealingHackType JSArray is not allocated on - // the heap. For the same reason, it's OK not to report extra cost. -} - -JSArray::JSArray(NonNullPassRefPtr<Structure> structure) - : JSObject(structure) -{ - unsigned initialCapacity = 0; - - m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity))); - m_storage->m_allocBase = m_storage; - m_indexBias = 0; - m_vectorLength = initialCapacity; - - checkConsistency(); - - Heap::heap(this)->reportExtraMemoryCost(storageSize(0)); -} - -JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength, ArrayCreationMode creationMode) - : JSObject(structure) -{ - unsigned initialCapacity; - if (creationMode == CreateCompact) - initialCapacity = initialLength; - else - initialCapacity = min(BASE_VECTOR_LEN, MIN_SPARSE_ARRAY_INDEX); - - m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity))); - m_storage->m_allocBase = m_storage; - m_storage->m_length = initialLength; - m_indexBias = 0; - m_vectorLength = initialCapacity; - m_storage->m_sparseValueMap = 0; - m_storage->subclassData = 0; - m_storage->reportedMapCapacity = 0; - - if (creationMode == CreateCompact) { -#if CHECK_ARRAY_CONSISTENCY - m_storage->m_inCompactInitialization = !!initialCapacity; -#endif - m_storage->m_length = 0; - m_storage->m_numValuesInVector = initialCapacity; - } else { -#if CHECK_ARRAY_CONSISTENCY - storage->m_inCompactInitialization = false; -#endif - m_storage->m_length = initialLength; - m_storage->m_numValuesInVector = 0; - JSValue* vector = m_storage->m_vector; - for (size_t i = 0; i < initialCapacity; ++i) - vector[i] = JSValue(); - } - - checkConsistency(); - - Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity)); -} - -JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) - : JSObject(structure) -{ - unsigned initialCapacity = list.size(); - unsigned initialStorage; - - // If the ArgList is empty, allocate space for 3 entries. This value empirically - // works well for benchmarks. - if (!initialCapacity) - initialStorage = 3; - else - initialStorage = initialCapacity; - - m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialStorage))); - m_storage->m_allocBase = m_storage; - m_indexBias = 0; - m_storage->m_length = initialCapacity; - m_vectorLength = initialStorage; - m_storage->m_numValuesInVector = initialCapacity; - m_storage->m_sparseValueMap = 0; - m_storage->subclassData = 0; - m_storage->reportedMapCapacity = 0; -#if CHECK_ARRAY_CONSISTENCY - m_storage->m_inCompactInitialization = false; -#endif - - size_t i = 0; - JSValue* vector = m_storage->m_vector; - ArgList::const_iterator end = list.end(); - for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i) - vector[i] = *it; - for (; i < initialStorage; i++) - vector[i] = JSValue(); - - checkConsistency(); - - Heap::heap(this)->reportExtraMemoryCost(storageSize(initialStorage)); -} - -JSArray::~JSArray() -{ - ASSERT(vptr() == JSGlobalData::jsArrayVPtr); - checkConsistency(DestructorConsistencyCheck); - - delete m_storage->m_sparseValueMap; - fastFree(m_storage->m_allocBase); -} - -bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) -{ - ArrayStorage* storage = m_storage; - - if (i >= storage->m_length) { - if (i > MAX_ARRAY_INDEX) - return getOwnPropertySlot(exec, Identifier::from(exec, i), slot); - return false; - } - - if (i < m_vectorLength) { - JSValue& valueSlot = storage->m_vector[i]; - if (valueSlot) { - slot.setValueSlot(&valueSlot); - return true; - } - } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - if (i >= MIN_SPARSE_ARRAY_INDEX) { - SparseArrayValueMap::iterator it = map->find(i); - if (it != map->end()) { - slot.setValueSlot(&it->second); - return true; - } - } - } - - return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, i), slot); -} - -bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (propertyName == exec->propertyNames().length) { - slot.setValue(jsNumber(length())); - return true; - } - - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex) - return JSArray::getOwnPropertySlot(exec, i, slot); - - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (propertyName == exec->propertyNames().length) { - descriptor.setDescriptor(jsNumber(length()), DontDelete | DontEnum); - return true; - } - - ArrayStorage* storage = m_storage; - - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex) { - if (i >= storage->m_length) - return false; - if (i < m_vectorLength) { - JSValue& value = storage->m_vector[i]; - if (value) { - descriptor.setDescriptor(value, 0); - return true; - } - } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - if (i >= MIN_SPARSE_ARRAY_INDEX) { - SparseArrayValueMap::iterator it = map->find(i); - if (it != map->end()) { - descriptor.setDescriptor(it->second, 0); - return true; - } - } - } - } - return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - -// ECMA 15.4.5.1 -void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex) { - put(exec, i, value); - return; - } - - if (propertyName == exec->propertyNames().length) { - unsigned newLength = value.toUInt32(exec); - if (value.toNumber(exec) != static_cast<double>(newLength)) { - throwError(exec, createRangeError(exec, "Invalid array length.")); - return; - } - setLength(newLength); - return; - } - - JSObject::put(exec, propertyName, value, slot); -} - -void JSArray::put(ExecState* exec, unsigned i, JSValue value) -{ - checkConsistency(); - - ArrayStorage* storage = m_storage; - - unsigned length = storage->m_length; - if (i >= length && i <= MAX_ARRAY_INDEX) { - length = i + 1; - storage->m_length = length; - } - - if (i < m_vectorLength) { - JSValue& valueSlot = storage->m_vector[i]; - if (valueSlot) { - valueSlot = value; - checkConsistency(); - return; - } - valueSlot = value; - ++storage->m_numValuesInVector; - checkConsistency(); - return; - } - - putSlowCase(exec, i, value); -} - -NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue value) -{ - ArrayStorage* storage = m_storage; - - SparseArrayValueMap* map = storage->m_sparseValueMap; - - if (i >= MIN_SPARSE_ARRAY_INDEX) { - if (i > MAX_ARRAY_INDEX) { - PutPropertySlot slot; - put(exec, Identifier::from(exec, i), value, slot); - return; - } - - // We miss some cases where we could compact the storage, such as a large array that is being filled from the end - // (which will only be compacted as we reach indices that are less than MIN_SPARSE_ARRAY_INDEX) - but this makes the check much faster. - if ((i > MAX_STORAGE_VECTOR_INDEX) || !isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) { - if (!map) { - map = new SparseArrayValueMap; - storage->m_sparseValueMap = map; - } - - pair<SparseArrayValueMap::iterator, bool> result = map->add(i, value); - if (!result.second) { // pre-existing entry - result.first->second = value; - return; - } - - size_t capacity = map->capacity(); - if (capacity != storage->reportedMapCapacity) { - Heap::heap(this)->reportExtraMemoryCost((capacity - storage->reportedMapCapacity) * (sizeof(unsigned) + sizeof(JSValue))); - storage->reportedMapCapacity = capacity; - } - return; - } - } - - // We have decided that we'll put the new item into the vector. - // Fast case is when there is no sparse map, so we can increase the vector size without moving values from it. - if (!map || map->isEmpty()) { - if (increaseVectorLength(i + 1)) { - storage = m_storage; - storage->m_vector[i] = value; - ++storage->m_numValuesInVector; - checkConsistency(); - } else - throwOutOfMemoryError(exec); - return; - } - - // Decide how many values it would be best to move from the map. - unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; - unsigned newVectorLength = getNewVectorLength(i + 1); - for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) - newNumValuesInVector += map->contains(j); - if (i >= MIN_SPARSE_ARRAY_INDEX) - newNumValuesInVector -= map->contains(i); - if (isDenseEnoughForVector(newVectorLength, newNumValuesInVector)) { - unsigned needLength = max(i + 1, storage->m_length); - unsigned proposedNewNumValuesInVector = newNumValuesInVector; - // If newVectorLength is already the maximum - MAX_STORAGE_VECTOR_LENGTH - then do not attempt to grow any further. - while ((newVectorLength < needLength) && (newVectorLength < MAX_STORAGE_VECTOR_LENGTH)) { - unsigned proposedNewVectorLength = getNewVectorLength(newVectorLength + 1); - for (unsigned j = max(newVectorLength, MIN_SPARSE_ARRAY_INDEX); j < proposedNewVectorLength; ++j) - proposedNewNumValuesInVector += map->contains(j); - if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector)) - break; - newVectorLength = proposedNewVectorLength; - newNumValuesInVector = proposedNewNumValuesInVector; - } - } - - void* baseStorage = storage->m_allocBase; - - if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage)) { - throwOutOfMemoryError(exec); - return; - } - - m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue)); - m_storage->m_allocBase = baseStorage; - storage = m_storage; - - unsigned vectorLength = m_vectorLength; - JSValue* vector = storage->m_vector; - - if (newNumValuesInVector == storage->m_numValuesInVector + 1) { - for (unsigned j = vectorLength; j < newVectorLength; ++j) - 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) - vector[j] = JSValue(); - for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j) - vector[j] = map->take(j); - } - - ASSERT(i < newVectorLength); - - m_vectorLength = newVectorLength; - storage->m_numValuesInVector = newNumValuesInVector; - - storage->m_vector[i] = value; - - checkConsistency(); - - Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); -} - -bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(isArrayIndex); - if (isArrayIndex) - return deleteProperty(exec, i); - - if (propertyName == exec->propertyNames().length) - return false; - - return JSObject::deleteProperty(exec, propertyName); -} - -bool JSArray::deleteProperty(ExecState* exec, unsigned i) -{ - checkConsistency(); - - ArrayStorage* storage = m_storage; - - if (i < m_vectorLength) { - JSValue& valueSlot = storage->m_vector[i]; - if (!valueSlot) { - checkConsistency(); - return false; - } - valueSlot = JSValue(); - --storage->m_numValuesInVector; - checkConsistency(); - return true; - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - if (i >= MIN_SPARSE_ARRAY_INDEX) { - SparseArrayValueMap::iterator it = map->find(i); - if (it != map->end()) { - map->remove(it); - checkConsistency(); - return true; - } - } - } - - checkConsistency(); - - if (i > MAX_ARRAY_INDEX) - return deleteProperty(exec, Identifier::from(exec, i)); - - return false; -} - -void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - // FIXME: Filling PropertyNameArray with an identifier for every integer - // is incredibly inefficient for large arrays. We need a different approach, - // which almost certainly means a different structure for PropertyNameArray. - - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(storage->m_length, m_vectorLength); - for (unsigned i = 0; i < usedVectorLength; ++i) { - if (storage->m_vector[i]) - propertyNames.add(Identifier::from(exec, i)); - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - propertyNames.add(Identifier::from(exec, it->first)); - } - - if (mode == IncludeDontEnumProperties) - propertyNames.add(exec->propertyNames().length); - - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -ALWAYS_INLINE unsigned JSArray::getNewVectorLength(unsigned desiredLength) -{ - ASSERT(desiredLength <= MAX_STORAGE_VECTOR_LENGTH); - - unsigned increasedLength; - unsigned maxInitLength = min(m_storage->m_length, 100000U); - - if (desiredLength < maxInitLength) - increasedLength = maxInitLength; - else if (!m_vectorLength) - increasedLength = max(desiredLength, lastArraySize); - else { - // Mathematically equivalent to: - // increasedLength = (newLength * 3 + 1) / 2; - // or: - // increasedLength = (unsigned)ceil(newLength * 1.5)); - // This form is not prone to internal overflow. - increasedLength = desiredLength + (desiredLength >> 1) + (desiredLength & 1); - } - - ASSERT(increasedLength >= desiredLength); - - lastArraySize = min(increasedLength, FIRST_VECTOR_GROW); - - return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH); -} - -bool JSArray::increaseVectorLength(unsigned newLength) -{ - // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map - // to the vector. Callers have to account for that, because they can do it more efficiently. - - ArrayStorage* storage = m_storage; - - unsigned vectorLength = m_vectorLength; - ASSERT(newLength > vectorLength); - ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); - unsigned newVectorLength = getNewVectorLength(newLength); - void* baseStorage = storage->m_allocBase; - - if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage)) - return false; - - storage = m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue)); - m_storage->m_allocBase = baseStorage; - - JSValue* vector = storage->m_vector; - for (unsigned i = vectorLength; i < newVectorLength; ++i) - vector[i] = JSValue(); - - m_vectorLength = newVectorLength; - - Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - - return true; -} - -bool JSArray::increaseVectorPrefixLength(unsigned newLength) -{ - // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map - // to the vector. Callers have to account for that, because they can do it more efficiently. - - ArrayStorage* storage = m_storage; - - unsigned vectorLength = m_vectorLength; - ASSERT(newLength > vectorLength); - ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX); - unsigned newVectorLength = getNewVectorLength(newLength); - - void* newBaseStorage = fastMalloc(storageSize(newVectorLength + m_indexBias)); - if (!newBaseStorage) - return false; - - m_indexBias += newVectorLength - newLength; - - m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(newBaseStorage) + m_indexBias * sizeof(JSValue)); - - memcpy(m_storage, storage, storageSize(0)); - memcpy(&m_storage->m_vector[newLength - m_vectorLength], &storage->m_vector[0], vectorLength * sizeof(JSValue)); - - m_storage->m_allocBase = newBaseStorage; - m_vectorLength = newLength; - - fastFree(storage->m_allocBase); - - Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - - return true; -} - - -void JSArray::setLength(unsigned newLength) -{ - ArrayStorage* storage = m_storage; - -#if CHECK_ARRAY_CONSISTENCY - if (!storage->m_inCompactInitialization) - checkConsistency(); - else - storage->m_inCompactInitialization = false; -#endif - - unsigned length = storage->m_length; - - if (newLength < length) { - unsigned usedVectorLength = min(length, m_vectorLength); - for (unsigned i = newLength; i < usedVectorLength; ++i) { - JSValue& valueSlot = storage->m_vector[i]; - bool hadValue = valueSlot; - valueSlot = JSValue(); - storage->m_numValuesInVector -= hadValue; - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap copy = *map; - SparseArrayValueMap::iterator end = copy.end(); - for (SparseArrayValueMap::iterator it = copy.begin(); it != end; ++it) { - if (it->first >= newLength) - map->remove(it->first); - } - if (map->isEmpty()) { - delete map; - storage->m_sparseValueMap = 0; - } - } - } - - storage->m_length = newLength; - - checkConsistency(); -} - -JSValue JSArray::pop() -{ - checkConsistency(); - - ArrayStorage* storage = m_storage; - - unsigned length = storage->m_length; - if (!length) - return jsUndefined(); - - --length; - - JSValue result; - - if (length < m_vectorLength) { - JSValue& valueSlot = storage->m_vector[length]; - if (valueSlot) { - --storage->m_numValuesInVector; - result = valueSlot; - valueSlot = JSValue(); - } else - result = jsUndefined(); - } else { - result = jsUndefined(); - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator it = map->find(length); - if (it != map->end()) { - result = it->second; - map->remove(it); - if (map->isEmpty()) { - delete map; - storage->m_sparseValueMap = 0; - } - } - } - } - - storage->m_length = length; - - checkConsistency(); - - return result; -} - -void JSArray::push(ExecState* exec, JSValue value) -{ - checkConsistency(); - - ArrayStorage* storage = m_storage; - - if (storage->m_length < m_vectorLength) { - storage->m_vector[storage->m_length] = value; - ++storage->m_numValuesInVector; - ++storage->m_length; - checkConsistency(); - return; - } - - if (storage->m_length < MIN_SPARSE_ARRAY_INDEX) { - SparseArrayValueMap* map = storage->m_sparseValueMap; - if (!map || map->isEmpty()) { - if (increaseVectorLength(storage->m_length + 1)) { - storage = m_storage; - storage->m_vector[storage->m_length] = value; - ++storage->m_numValuesInVector; - ++storage->m_length; - checkConsistency(); - return; - } - checkConsistency(); - throwOutOfMemoryError(exec); - return; - } - } - - putSlowCase(exec, storage->m_length++, value); -} - -void JSArray::shiftCount(ExecState* exec, int count) -{ - ASSERT(count > 0); - - ArrayStorage* storage = m_storage; - - unsigned oldLength = storage->m_length; - - if (!oldLength) - return; - - if (oldLength != storage->m_numValuesInVector) { - // If m_length and m_numValuesInVector aren't the same, we have a sparse vector - // which means we need to go through each entry looking for the the "empty" - // slots and then fill them with possible properties. See ECMA spec. - // 15.4.4.9 steps 11 through 13. - for (unsigned i = count; i < oldLength; ++i) { - if ((i >= m_vectorLength) || (!m_storage->m_vector[i])) { - PropertySlot slot(this); - JSValue p = prototype(); - if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot))) - put(exec, i, slot.getValue(exec, i)); - } - } - - storage = m_storage; // The put() above could have grown the vector and realloc'ed storage. - - // Need to decrement numValuesInvector based on number of real entries - for (unsigned i = 0; i < (unsigned)count; ++i) - if ((i < m_vectorLength) && (storage->m_vector[i])) - --storage->m_numValuesInVector; - } else - storage->m_numValuesInVector -= count; - - storage->m_length -= count; - - if (m_vectorLength) { - count = min(m_vectorLength, (unsigned)count); - - m_vectorLength -= count; - - if (m_vectorLength) { - char* newBaseStorage = reinterpret_cast<char*>(storage) + count * sizeof(JSValue); - memmove(newBaseStorage, storage, storageSize(0)); - m_storage = reinterpret_cast_ptr<ArrayStorage*>(newBaseStorage); - - m_indexBias += count; - } - } -} - -void JSArray::unshiftCount(ExecState* exec, int count) -{ - ArrayStorage* storage = m_storage; - - ASSERT(m_indexBias >= 0); - ASSERT(count >= 0); - - unsigned length = storage->m_length; - - if (length != storage->m_numValuesInVector) { - // If m_length and m_numValuesInVector aren't the same, we have a sparse vector - // which means we need to go through each entry looking for the the "empty" - // slots and then fill them with possible properties. See ECMA spec. - // 15.4.4.13 steps 8 through 10. - for (unsigned i = 0; i < length; ++i) { - if ((i >= m_vectorLength) || (!m_storage->m_vector[i])) { - PropertySlot slot(this); - JSValue p = prototype(); - if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot))) - put(exec, i, slot.getValue(exec, i)); - } - } - } - - storage = m_storage; // The put() above could have grown the vector and realloc'ed storage. - - if (m_indexBias >= count) { - m_indexBias -= count; - char* newBaseStorage = reinterpret_cast<char*>(storage) - count * sizeof(JSValue); - memmove(newBaseStorage, storage, storageSize(0)); - m_storage = reinterpret_cast_ptr<ArrayStorage*>(newBaseStorage); - m_vectorLength += count; - } else if (!increaseVectorPrefixLength(m_vectorLength + count)) { - throwOutOfMemoryError(exec); - return; - } - - JSValue* vector = m_storage->m_vector; - for (int i = 0; i < count; i++) - vector[i] = JSValue(); -} - -void JSArray::markChildren(MarkStack& markStack) -{ - markChildrenDirect(markStack); -} - -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); -} - -static int compareByStringPairForQSort(const void* a, const void* b) -{ - const ValueStringPair* va = static_cast<const ValueStringPair*>(a); - const ValueStringPair* vb = static_cast<const ValueStringPair*>(b); - return codePointCompare(va->second, vb->second); -} - -void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) -{ - ArrayStorage* storage = m_storage; - - unsigned lengthNotIncludingUndefined = compactForSorting(); - if (storage->m_sparseValueMap) { - throwOutOfMemoryError(exec); - return; - } - - if (!lengthNotIncludingUndefined) - return; - - bool allValuesAreNumbers = true; - size_t size = storage->m_numValuesInVector; - for (size_t i = 0; i < size; ++i) { - if (!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(storage->m_vector, size, sizeof(JSValue), compareNumbersForQSort); - - checkConsistency(SortConsistencyCheck); -} - -void JSArray::sort(ExecState* exec) -{ - ArrayStorage* storage = m_storage; - - unsigned lengthNotIncludingUndefined = compactForSorting(); - if (storage->m_sparseValueMap) { - throwOutOfMemoryError(exec); - return; - } - - if (!lengthNotIncludingUndefined) - return; - - // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that. - // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary - // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return - // random or otherwise changing results, effectively making compare function inconsistent. - - Vector<ValueStringPair> values(lengthNotIncludingUndefined); - if (!values.begin()) { - throwOutOfMemoryError(exec); - return; - } - - Heap::heap(this)->pushTempSortVector(&values); - - for (size_t i = 0; i < lengthNotIncludingUndefined; i++) { - JSValue value = storage->m_vector[i]; - ASSERT(!value.isUndefined()); - values[i].first = value; - } - - // FIXME: The following loop continues to call toString on subsequent values even after - // a toString call raises an exception. - - for (size_t i = 0; i < lengthNotIncludingUndefined; i++) - values[i].second = values[i].first.toString(exec); - - if (exec->hadException()) - return; - - // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather - // than O(N log N). - -#if HAVE(MERGESORT) - mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); -#else - // FIXME: The qsort library function is likely to not be a stable sort. - // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort. - qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); -#endif - - // If the toString function changed the length of the array or vector storage, - // increase the length to handle the orignal number of actual values. - if (m_vectorLength < lengthNotIncludingUndefined) - increaseVectorLength(lengthNotIncludingUndefined); - if (storage->m_length < lengthNotIncludingUndefined) - storage->m_length = lengthNotIncludingUndefined; - - for (size_t i = 0; i < lengthNotIncludingUndefined; i++) - storage->m_vector[i] = values[i].first; - - Heap::heap(this)->popTempSortVector(&values); - - checkConsistency(SortConsistencyCheck); -} - -struct AVLTreeNodeForArrayCompare { - JSValue value; - - // Child pointers. The high bit of gt is robbed and used as the - // balance factor sign. The high bit of lt is robbed and used as - // the magnitude of the balance factor. - int32_t gt; - int32_t lt; -}; - -struct AVLTreeAbstractorForArrayCompare { - typedef int32_t handle; // Handle is an index into m_nodes vector. - typedef JSValue key; - typedef int32_t size; - - Vector<AVLTreeNodeForArrayCompare> m_nodes; - ExecState* m_exec; - JSValue m_compareFunction; - CallType m_compareCallType; - const CallData* m_compareCallData; - JSValue m_globalThisValue; - OwnPtr<CachedCall> m_cachedCall; - - handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; } - void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; } - handle get_greater(handle h) { return m_nodes[h].gt & 0x7FFFFFFF; } - void set_greater(handle h, handle gh) { m_nodes[h].gt &= 0x80000000; m_nodes[h].gt |= gh; } - - int get_balance_factor(handle h) - { - if (m_nodes[h].gt & 0x80000000) - return -1; - return static_cast<unsigned>(m_nodes[h].lt) >> 31; - } - - void set_balance_factor(handle h, int bf) - { - if (bf == 0) { - m_nodes[h].lt &= 0x7FFFFFFF; - m_nodes[h].gt &= 0x7FFFFFFF; - } else { - m_nodes[h].lt |= 0x80000000; - if (bf < 0) - m_nodes[h].gt |= 0x80000000; - else - m_nodes[h].gt &= 0x7FFFFFFF; - } - } - - int compare_key_key(key va, key vb) - { - ASSERT(!va.isUndefined()); - ASSERT(!vb.isUndefined()); - - if (m_exec->hadException()) - return 1; - - double compareResult; - if (m_cachedCall) { - m_cachedCall->setThis(m_globalThisValue); - m_cachedCall->setArgument(0, va); - m_cachedCall->setArgument(1, vb); - compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec)); - } else { - MarkedArgumentBuffer arguments; - arguments.append(va); - arguments.append(vb); - compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec); - } - return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent. - } - - int compare_key_node(key k, handle h) { return compare_key_key(k, m_nodes[h].value); } - int compare_node_node(handle h1, handle h2) { return compare_key_key(m_nodes[h1].value, m_nodes[h2].value); } - - static handle null() { return 0x7FFFFFFF; } -}; - -void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) -{ - checkConsistency(); - - ArrayStorage* storage = m_storage; - - // FIXME: This ignores exceptions raised in the compare function or in toNumber. - - // The maximum tree depth is compiled in - but the caller is clearly up to no good - // if a larger array is passed. - ASSERT(storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max())); - if (storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max())) - return; - - unsigned usedVectorLength = min(storage->m_length, m_vectorLength); - unsigned nodeCount = usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0); - - if (!nodeCount) - return; - - AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items - tree.abstractor().m_exec = exec; - tree.abstractor().m_compareFunction = compareFunction; - tree.abstractor().m_compareCallType = callType; - tree.abstractor().m_compareCallData = &callData; - tree.abstractor().m_globalThisValue = exec->globalThisValue(); - tree.abstractor().m_nodes.grow(nodeCount); - - if (callType == CallTypeJS) - tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, asFunction(compareFunction), 2)); - - if (!tree.abstractor().m_nodes.begin()) { - throwOutOfMemoryError(exec); - return; - } - - // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified - // right out from under us while we're building the tree here. - - unsigned numDefined = 0; - unsigned numUndefined = 0; - - // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree. - for (; numDefined < usedVectorLength; ++numDefined) { - JSValue v = storage->m_vector[numDefined]; - if (!v || v.isUndefined()) - break; - tree.abstractor().m_nodes[numDefined].value = v; - tree.insert(numDefined); - } - for (unsigned i = numDefined; i < usedVectorLength; ++i) { - JSValue v = storage->m_vector[i]; - if (v) { - if (v.isUndefined()) - ++numUndefined; - else { - tree.abstractor().m_nodes[numDefined].value = v; - tree.insert(numDefined); - ++numDefined; - } - } - } - - unsigned newUsedVectorLength = numDefined + numUndefined; - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_vectorLength) { - // Check that it is possible to allocate an array large enough to hold all the entries. - if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) { - throwOutOfMemoryError(exec); - return; - } - } - - storage = m_storage; - - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) { - tree.abstractor().m_nodes[numDefined].value = it->second; - tree.insert(numDefined); - ++numDefined; - } - - delete map; - storage->m_sparseValueMap = 0; - } - - ASSERT(tree.abstractor().m_nodes.size() >= numDefined); - - // FIXME: If the compare function changed the length of the array, the following might be - // modifying the vector incorrectly. - - // Copy the values back into m_storage. - AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter; - iter.start_iter_least(tree); - for (unsigned i = 0; i < numDefined; ++i) { - storage->m_vector[i] = tree.abstractor().m_nodes[*iter].value; - ++iter; - } - - // Put undefined values back in. - for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - storage->m_vector[i] = jsUndefined(); - - // Ensure that unused values in the vector are zeroed out. - for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - storage->m_vector[i] = JSValue(); - - storage->m_numValuesInVector = newUsedVectorLength; - - checkConsistency(SortConsistencyCheck); -} - -void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) -{ - ArrayStorage* storage = m_storage; - - JSValue* vector = storage->m_vector; - unsigned vectorEnd = min(storage->m_length, m_vectorLength); - unsigned i = 0; - for (; i < vectorEnd; ++i) { - JSValue& v = vector[i]; - if (!v) - break; - args.append(v); - } - - for (; i < storage->m_length; ++i) - args.append(get(exec, i)); -} - -void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize) -{ - ASSERT(m_storage->m_length >= maxSize); - UNUSED_PARAM(maxSize); - JSValue* vector = m_storage->m_vector; - unsigned vectorEnd = min(maxSize, m_vectorLength); - unsigned i = 0; - for (; i < vectorEnd; ++i) { - JSValue& v = vector[i]; - if (!v) - break; - buffer[i] = v; - } - - for (; i < maxSize; ++i) - buffer[i] = get(exec, i); -} - -unsigned JSArray::compactForSorting() -{ - checkConsistency(); - - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(storage->m_length, m_vectorLength); - - unsigned numDefined = 0; - unsigned numUndefined = 0; - - for (; numDefined < usedVectorLength; ++numDefined) { - JSValue v = storage->m_vector[numDefined]; - if (!v || v.isUndefined()) - break; - } - for (unsigned i = numDefined; i < usedVectorLength; ++i) { - JSValue v = storage->m_vector[i]; - if (v) { - if (v.isUndefined()) - ++numUndefined; - else - storage->m_vector[numDefined++] = v; - } - } - - unsigned newUsedVectorLength = numDefined + numUndefined; - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_vectorLength) { - // Check that it is possible to allocate an array large enough to hold all the entries - if not, - // exception is thrown by caller. - if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) - return 0; - - storage = m_storage; - } - - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - storage->m_vector[numDefined++] = it->second; - - delete map; - storage->m_sparseValueMap = 0; - } - - for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - storage->m_vector[i] = jsUndefined(); - for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - storage->m_vector[i] = JSValue(); - - storage->m_numValuesInVector = newUsedVectorLength; - - checkConsistency(SortConsistencyCheck); - - return numDefined; -} - -void* JSArray::subclassData() const -{ - return m_storage->subclassData; -} - -void JSArray::setSubclassData(void* d) -{ - m_storage->subclassData = d; -} - -#if CHECK_ARRAY_CONSISTENCY - -void JSArray::checkConsistency(ConsistencyCheckType type) -{ - ArrayStorage* storage = m_storage; - - ASSERT(storage); - if (type == SortConsistencyCheck) - ASSERT(!storage->m_sparseValueMap); - - unsigned numValuesInVector = 0; - for (unsigned i = 0; i < m_vectorLength; ++i) { - if (JSValue value = storage->m_vector[i]) { - ASSERT(i < storage->m_length); - if (type != DestructorConsistencyCheck) - value.isUndefined(); // Likely to crash if the object was deallocated. - ++numValuesInVector; - } else { - if (type == SortConsistencyCheck) - ASSERT(i >= storage->m_numValuesInVector); - } - } - ASSERT(numValuesInVector == storage->m_numValuesInVector); - ASSERT(numValuesInVector <= storage->m_length); - - if (storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = storage->m_sparseValueMap->end(); - for (SparseArrayValueMap::iterator it = storage->m_sparseValueMap->begin(); it != end; ++it) { - unsigned index = it->first; - ASSERT(index < storage->m_length); - ASSERT(index >= storage->m_vectorLength); - ASSERT(index <= MAX_ARRAY_INDEX); - ASSERT(it->second); - if (type != DestructorConsistencyCheck) - it->second.isUndefined(); // Likely to crash if the object was deallocated. - } - } -} - -#endif - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h deleted file mode 100644 index de28b65..0000000 --- a/JavaScriptCore/runtime/JSArray.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef JSArray_h -#define JSArray_h - -#include "JSObject.h" - -#define CHECK_ARRAY_CONSISTENCY 0 - -namespace JSC { - - typedef HashMap<unsigned, JSValue> SparseArrayValueMap; - - // This struct holds the actual data values of an array. A JSArray object points to it's contained ArrayStorage - // struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and - // setStorage() methods. It is important to note that there may be space before the ArrayStorage that - // is used to quick unshift / shift operation. The actual allocated pointer is available by using: - // getStorage() - m_indexBias * sizeof(JSValue) - struct ArrayStorage { - unsigned m_length; // The "length" property on the array - unsigned m_numValuesInVector; - SparseArrayValueMap* m_sparseValueMap; - void* subclassData; // A JSArray subclass can use this to fill the vector lazily. - void* m_allocBase; // Pointer to base address returned by malloc(). Keeping this pointer does eliminate false positives from the leak detector. - size_t reportedMapCapacity; -#if CHECK_ARRAY_CONSISTENCY - bool m_inCompactInitialization; -#endif - JSValue m_vector[1]; - }; - - // The CreateCompact creation mode is used for fast construction of arrays - // whose size and contents are known at time of creation. - // - // There are two obligations when using this mode: - // - // - uncheckedSetIndex() must be used when initializing the array. - // - setLength() must be called after initialization. - - enum ArrayCreationMode { CreateCompact, CreateInitialized }; - - class JSArray : public JSObject { - friend class JIT; - friend class Walker; - - public: - enum VPtrStealingHackType { VPtrStealingHack }; - JSArray(VPtrStealingHackType); - - explicit JSArray(NonNullPassRefPtr<Structure>); - JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength, ArrayCreationMode); - JSArray(NonNullPassRefPtr<Structure>, const ArgList& initialValues); - virtual ~JSArray(); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem. - - static JS_EXPORTDATA const ClassInfo info; - - unsigned length() const { return m_storage->m_length; } - void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray. - - void sort(ExecState*); - void sort(ExecState*, JSValue compareFunction, CallType, const CallData&); - void sortNumeric(ExecState*, JSValue compareFunction, CallType, const CallData&); - - void push(ExecState*, JSValue); - JSValue pop(); - - void shiftCount(ExecState*, int count); - void unshiftCount(ExecState*, int count); - - bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; } - JSValue getIndex(unsigned i) - { - ASSERT(canGetIndex(i)); - return m_storage->m_vector[i]; - } - - bool canSetIndex(unsigned i) { return i < m_vectorLength; } - void setIndex(unsigned i, JSValue v) - { - ASSERT(canSetIndex(i)); - - JSValue& x = m_storage->m_vector[i]; - if (!x) { - ArrayStorage *storage = m_storage; - ++storage->m_numValuesInVector; - if (i >= storage->m_length) - storage->m_length = i + 1; - } - x = v; - } - - void uncheckedSetIndex(unsigned i, JSValue v) - { - ASSERT(canSetIndex(i)); - ArrayStorage *storage = m_storage; -#if CHECK_ARRAY_CONSISTENCY - ASSERT(storage->m_inCompactInitialization); -#endif - storage->m_vector[i] = v; - } - - void fillArgList(ExecState*, MarkedArgumentBuffer&); - void copyToRegisters(ExecState*, Register*, uint32_t); - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - inline void markChildrenDirect(MarkStack& markStack); - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual bool deleteProperty(ExecState*, unsigned propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - virtual void markChildren(MarkStack&); - - void* subclassData() const; - void setSubclassData(void*); - - private: - virtual const ClassInfo* classInfo() const { return &info; } - - bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&); - void putSlowCase(ExecState*, unsigned propertyName, JSValue); - - unsigned getNewVectorLength(unsigned desiredLength); - bool increaseVectorLength(unsigned newLength); - bool increaseVectorPrefixLength(unsigned newLength); - - unsigned compactForSorting(); - - enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck }; - void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck); - - unsigned m_vectorLength; // The valid length of m_vector - int m_indexBias; // The number of JSValue sized blocks before ArrayStorage. - ArrayStorage *m_storage; - }; - - JSArray* asArray(JSValue); - - inline JSArray* asArray(JSCell* cell) - { - ASSERT(cell->inherits(&JSArray::info)); - return static_cast<JSArray*>(cell); - } - - inline JSArray* asArray(JSValue value) - { - return asArray(value.asCell()); - } - - inline bool isJSArray(JSGlobalData* globalData, JSValue v) - { - return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; - } - inline bool isJSArray(JSGlobalData* globalData, JSCell* cell) { return cell->vptr() == globalData->jsArrayVPtr; } - - inline void JSArray::markChildrenDirect(MarkStack& markStack) - { - JSObject::markChildrenDirect(markStack); - - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength); - markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues); - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - markStack.append(it->second); - } - } - - inline void MarkStack::markChildren(JSCell* cell) - { - ASSERT(Heap::isCellMarked(cell)); - if (!cell->structure()->typeInfo().overridesMarkChildren()) { -#ifdef NDEBUG - asObject(cell)->markChildrenDirect(*this); -#else - ASSERT(!m_isCheckingForDefaultMarkViolation); - m_isCheckingForDefaultMarkViolation = true; - cell->markChildren(*this); - ASSERT(m_isCheckingForDefaultMarkViolation); - m_isCheckingForDefaultMarkViolation = false; -#endif - return; - } - if (cell->vptr() == m_jsArrayVPtr) { - asArray(cell)->markChildrenDirect(*this); - return; - } - cell->markChildren(*this); - } - - inline void MarkStack::drain() - { -#if !ASSERT_DISABLED - ASSERT(!m_isDraining); - m_isDraining = true; -#endif - while (!m_markSets.isEmpty() || !m_values.isEmpty()) { - while (!m_markSets.isEmpty() && m_values.size() < 50) { - ASSERT(!m_markSets.isEmpty()); - MarkSet& current = m_markSets.last(); - ASSERT(current.m_values); - JSValue* end = current.m_end; - ASSERT(current.m_values); - ASSERT(current.m_values != end); - findNextUnmarkedNullValue: - ASSERT(current.m_values != end); - JSValue value = *current.m_values; - current.m_values++; - - JSCell* cell; - if (!value || !value.isCell() || Heap::checkMarkCell(cell = value.asCell())) { - if (current.m_values == end) { - m_markSets.removeLast(); - continue; - } - goto findNextUnmarkedNullValue; - } - - if (cell->structure()->typeInfo().type() < CompoundType) { - if (current.m_values == end) { - m_markSets.removeLast(); - continue; - } - goto findNextUnmarkedNullValue; - } - - if (current.m_values == end) - m_markSets.removeLast(); - - markChildren(cell); - } - while (!m_values.isEmpty()) - markChildren(m_values.removeLast()); - } -#if !ASSERT_DISABLED - m_isDraining = false; -#endif - } - - // Rule from ECMA 15.2 about what an array index is. - // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. - inline unsigned Identifier::toArrayIndex(bool& ok) const - { - unsigned i = toUInt32(ok); - if (ok && i >= 0xFFFFFFFFU) - ok = false; - return i; - } - -} // namespace JSC - -#endif // JSArray_h diff --git a/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp deleted file mode 100644 index 6af9d75..0000000 --- a/JavaScriptCore/runtime/JSByteArray.cpp +++ /dev/null @@ -1,116 +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. - */ - -#include "config.h" -#include "JSByteArray.h" - -#include "JSGlobalObject.h" -#include "PropertyNameArray.h" - -using namespace WTF; - -namespace JSC { - -const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", 0, 0, 0 }; - -JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure, ByteArray* storage, const JSC::ClassInfo* classInfo) - : JSObject(structure) - , m_storage(storage) - , m_classInfo(classInfo) -{ - putDirect(exec->globalData().propertyNames->length, jsNumber(m_storage->length()), ReadOnly | DontDelete); -} - -#if !ASSERT_DISABLED -JSByteArray::~JSByteArray() -{ - ASSERT(vptr() == JSGlobalData::jsByteArrayVPtr); -} -#endif - - -PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) -{ - PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - return result; -} - -bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - bool ok; - unsigned index = propertyName.toUInt32(ok); - if (ok && canAccessIndex(index)) { - slot.setValue(getIndex(exec, index)); - return true; - } - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -bool JSByteArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - bool ok; - unsigned index = propertyName.toUInt32(ok); - if (ok && canAccessIndex(index)) { - descriptor.setDescriptor(getIndex(exec, index), DontDelete); - return true; - } - return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - -bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) -{ - if (canAccessIndex(propertyName)) { - slot.setValue(getIndex(exec, propertyName)); - return true; - } - return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); -} - -void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - bool ok; - unsigned index = propertyName.toUInt32(ok); - if (ok) { - setIndex(exec, index, value); - return; - } - JSObject::put(exec, propertyName, value, slot); -} - -void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value) -{ - setIndex(exec, propertyName, value); -} - -void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - unsigned length = m_storage->length(); - for (unsigned i = 0; i < length; ++i) - propertyNames.add(Identifier::from(exec, i)); - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -} - diff --git a/JavaScriptCore/runtime/JSByteArray.h b/JavaScriptCore/runtime/JSByteArray.h deleted file mode 100644 index 44bae2d..0000000 --- a/JavaScriptCore/runtime/JSByteArray.h +++ /dev/null @@ -1,116 +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 JSByteArray_h -#define JSByteArray_h - -#include "JSObject.h" - -#include <wtf/ByteArray.h> - -namespace JSC { - - class JSByteArray : public JSObject { - friend class JSGlobalData; - public: - bool canAccessIndex(unsigned i) { return i < m_storage->length(); } - JSValue getIndex(ExecState*, unsigned i) - { - ASSERT(canAccessIndex(i)); - return jsNumber(m_storage->data()[i]); - } - - void setIndex(unsigned i, int value) - { - ASSERT(canAccessIndex(i)); - m_storage->data()[i] = static_cast<unsigned char>(value); - } - - void setIndex(unsigned i, double value) - { - ASSERT(canAccessIndex(i)); - // The largest integer value that a double can represent without loss of precision - // is 2^53. long long is the smallest integral type that gives correct results - // when casting numbers larger than 2^31 from a value of type double. - m_storage->data()[i] = static_cast<unsigned char>(static_cast<long long>(value)); - } - - void setIndex(ExecState* exec, unsigned i, JSValue value) - { - double byteValue = value.toNumber(exec); - if (exec->hadException()) - return; - if (canAccessIndex(i)) - setIndex(i, byteValue); - } - - JSByteArray(ExecState* exec, NonNullPassRefPtr<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 bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); - virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue); - - virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - - virtual const ClassInfo* classInfo() const { return m_classInfo; } - static const ClassInfo s_defaultInfo; - - size_t length() const { return m_storage->length(); } - - WTF::ByteArray* storage() const { return m_storage.get(); } - -#if !ASSERT_DISABLED - virtual ~JSByteArray(); -#endif - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags; - - private: - enum VPtrStealingHackType { VPtrStealingHack }; - JSByteArray(VPtrStealingHackType) - : JSObject(createStructure(jsNull())) - , m_classInfo(0) - { - } - - RefPtr<WTF::ByteArray> m_storage; - const ClassInfo* m_classInfo; - }; - - JSByteArray* asByteArray(JSValue value); - inline JSByteArray* asByteArray(JSValue value) - { - return static_cast<JSByteArray*>(value.asCell()); - } - - inline bool isJSByteArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsByteArrayVPtr; } - -} // namespace JSC - -#endif // JSByteArray_h diff --git a/JavaScriptCore/runtime/JSCell.cpp b/JavaScriptCore/runtime/JSCell.cpp deleted file mode 100644 index 0cc1ab1..0000000 --- a/JavaScriptCore/runtime/JSCell.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSCell.h" - -#include "JSFunction.h" -#include "JSString.h" -#include "JSObject.h" -#include <wtf/MathExtras.h> - -namespace JSC { - -#if defined NAN && defined INFINITY - -extern const double NaN = NAN; -extern const double Inf = INFINITY; - -#else // !(defined NAN && defined INFINITY) - -// The trick is to define the NaN and Inf globals with a different type than the declaration. -// This trick works because the mangled name of the globals does not include the type, although -// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of -// characters don't necessarily need the same alignment doubles do, but for now it seems to work. -// It would be good to figure out a 100% clean way that still avoids code that runs at init time. - -// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere, -// while NaN_double has to be 4-byte aligned for 32-bits. -// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading. - -static const union { - struct { - unsigned char NaN_Bytes[8]; - unsigned char Inf_Bytes[8]; - } bytes; - - struct { - double NaN_Double; - double Inf_Double; - } doubles; - -} NaNInf = { { -#if CPU(BIG_ENDIAN) - { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, - { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } -#elif CPU(MIDDLE_ENDIAN) - { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }, - { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } -#else - { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }, - { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } -#endif -} } ; - -extern const double NaN = NaNInf.doubles.NaN_Double; -extern const double Inf = NaNInf.doubles.Inf_Double; - -#endif // !(defined NAN && defined INFINITY) - -bool JSCell::getUInt32(uint32_t&) const -{ - return false; -} - -bool JSCell::getString(ExecState* exec, UString&stringValue) const -{ - if (!isString()) - return false; - stringValue = static_cast<const JSString*>(this)->value(exec); - return true; -} - -UString JSCell::getString(ExecState* exec) const -{ - return isString() ? static_cast<const JSString*>(this)->value(exec) : UString(); -} - -JSObject* JSCell::getObject() -{ - return isObject() ? asObject(this) : 0; -} - -const JSObject* JSCell::getObject() const -{ - return isObject() ? static_cast<const JSObject*>(this) : 0; -} - -CallType JSCell::getCallData(CallData&) -{ - return CallTypeNone; -} - -ConstructType JSCell::getConstructData(ConstructData&) -{ - return ConstructTypeNone; -} - -bool JSCell::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot) -{ - // This is not a general purpose implementation of getOwnPropertySlot. - // It should only be called by JSValue::get. - // It calls getPropertySlot, not getOwnPropertySlot. - JSObject* object = toObject(exec); - slot.setBase(object); - if (!object->getPropertySlot(exec, identifier, slot)) - slot.setUndefined(); - return true; -} - -bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySlot& slot) -{ - // This is not a general purpose implementation of getOwnPropertySlot. - // It should only be called by JSValue::get. - // It calls getPropertySlot, not getOwnPropertySlot. - JSObject* object = toObject(exec); - slot.setBase(object); - if (!object->getPropertySlot(exec, identifier, slot)) - slot.setUndefined(); - return true; -} - -void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot) -{ - toObject(exec)->put(exec, identifier, value, slot); -} - -void JSCell::put(ExecState* exec, unsigned identifier, JSValue value) -{ - toObject(exec)->put(exec, identifier, value); -} - -bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier) -{ - return toObject(exec)->deleteProperty(exec, identifier); -} - -bool JSCell::deleteProperty(ExecState* exec, unsigned identifier) -{ - return toObject(exec)->deleteProperty(exec, identifier); -} - -JSObject* JSCell::toThisObject(ExecState* exec) const -{ - return toObject(exec); -} - -const ClassInfo* JSCell::classInfo() const -{ - return 0; -} - -JSValue JSCell::getJSNumber() -{ - return JSValue(); -} - -bool JSCell::isGetterSetter() const -{ - return false; -} - -JSValue JSCell::toPrimitive(ExecState*, PreferredPrimitiveType) const -{ - ASSERT_NOT_REACHED(); - return JSValue(); -} - -bool JSCell::getPrimitiveNumber(ExecState*, double&, JSValue&) -{ - ASSERT_NOT_REACHED(); - return false; -} - -bool JSCell::toBoolean(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return false; -} - -double JSCell::toNumber(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return 0; -} - -UString JSCell::toString(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return UString(); -} - -JSObject* JSCell::toObject(ExecState*) const -{ - ASSERT_NOT_REACHED(); - return 0; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h deleted file mode 100644 index 7d4929d..0000000 --- a/JavaScriptCore/runtime/JSCell.h +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSCell_h -#define JSCell_h - -#include "CallData.h" -#include "ConstructData.h" -#include "Collector.h" -#include "JSImmediate.h" -#include "JSValue.h" -#include "MarkStack.h" -#include "Structure.h" -#include <wtf/Noncopyable.h> - -namespace JSC { - -#if COMPILER(MSVC) - // If WTF_MAKE_NONCOPYABLE is applied to JSCell we end up with a bunch of - // undefined references to the JSCell copy constructor and assignment operator - // when linking JavaScriptCore. - class MSVCBugWorkaround { - WTF_MAKE_NONCOPYABLE(MSVCBugWorkaround); - - protected: - MSVCBugWorkaround() { } - ~MSVCBugWorkaround() { } - }; - - class JSCell : MSVCBugWorkaround { -#else - class JSCell { - WTF_MAKE_NONCOPYABLE(JSCell); -#endif - - 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 JSAPIValueWrapper; - friend class JSZombie; - friend class JSGlobalData; - - private: - explicit JSCell(Structure*); - virtual ~JSCell(); - - public: - static PassRefPtr<Structure> createDummyStructure() - { - return Structure::create(jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount); - } - - // Querying the type. - bool isString() const; - bool isObject() const; - virtual bool isGetterSetter() const; - bool inherits(const ClassInfo*) const; - virtual bool isAPIValueWrapper() const { return false; } - virtual bool isPropertyNameIterator() const { return false; } - - Structure* structure() const; - - // Extracting the value. - bool getString(ExecState* exec, UString&) const; - UString getString(ExecState* exec) const; // null string if not a string - JSObject* getObject(); // NULL if not an object - const JSObject* getObject() const; // NULL if not an object - - virtual CallType getCallData(CallData&); - virtual ConstructType getConstructData(ConstructData&); - - // Extracting integer values. - // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*. - virtual bool getUInt32(uint32_t&) const; - - // Basic conversions. - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); - virtual bool toBoolean(ExecState*) const; - virtual double toNumber(ExecState*) const; - virtual UString toString(ExecState*) const; - virtual JSObject* toObject(ExecState*) const; - - // Garbage collection. - void* operator new(size_t, ExecState*); - void* operator new(size_t, JSGlobalData*); - void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; } - - virtual void markChildren(MarkStack&); -#if ENABLE(JSC_ZOMBIES) - virtual bool isZombie() const { return false; } -#endif - - // Object operations, with the toObject operation included. - virtual const ClassInfo* classInfo() const; - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual void put(ExecState*, unsigned propertyName, JSValue); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual bool deleteProperty(ExecState*, unsigned propertyName); - - virtual JSObject* toThisObject(ExecState*) const; - virtual JSValue getJSNumber(); - void* vptr() { return *reinterpret_cast<void**>(this); } - void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; } - - // FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and - // fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always - // call this function, not its slower virtual counterpart. (For integer - // property names, we want a similar interface with appropriate optimizations.) - bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - - protected: - static const unsigned AnonymousSlotCount = 0; - - private: - // Base implementation; for non-object classes implements getPropertySlot. - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - - Structure* m_structure; - }; - - inline JSCell::JSCell(Structure* structure) - : m_structure(structure) - { - } - - inline JSCell::~JSCell() - { - } - - inline bool JSCell::isObject() const - { - return m_structure->typeInfo().type() == ObjectType; - } - - inline bool JSCell::isString() const - { - return m_structure->typeInfo().type() == StringType; - } - - inline Structure* JSCell::structure() const - { - return m_structure; - } - - inline void JSCell::markChildren(MarkStack&) - { - } - - inline void* JSCell::operator new(size_t size, JSGlobalData* globalData) - { - return globalData->heap.allocate(size); - } - - inline void* JSCell::operator new(size_t size, ExecState* exec) - { - return exec->heap()->allocate(size); - } - - // --- JSValue inlines ---------------------------- - - inline bool JSValue::isString() const - { - return isCell() && asCell()->isString(); - } - - inline bool JSValue::isGetterSetter() const - { - return isCell() && asCell()->isGetterSetter(); - } - - inline bool JSValue::isObject() const - { - return isCell() && asCell()->isObject(); - } - - inline bool JSValue::getString(ExecState* exec, UString& s) const - { - return isCell() && asCell()->getString(exec, s); - } - - inline UString JSValue::getString(ExecState* exec) const - { - return isCell() ? asCell()->getString(exec) : UString(); - } - - inline JSObject* JSValue::getObject() const - { - return isCell() ? asCell()->getObject() : 0; - } - - inline CallType getCallData(JSValue value, CallData& callData) - { - CallType result = value.isCell() ? value.asCell()->getCallData(callData) : CallTypeNone; - ASSERT(result == CallTypeNone || value.isValidCallee()); - return result; - } - - inline ConstructType getConstructData(JSValue value, ConstructData& constructData) - { - ConstructType result = value.isCell() ? value.asCell()->getConstructData(constructData) : ConstructTypeNone; - ASSERT(result == ConstructTypeNone || value.isValidCallee()); - return result; - } - - ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const - { - if (isInt32()) { - int32_t i = asInt32(); - v = static_cast<uint32_t>(i); - return i >= 0; - } - if (isDouble()) { - double d = asDouble(); - v = static_cast<uint32_t>(d); - return v == d; - } - return false; - } - -#if USE(JSVALUE64) - ALWAYS_INLINE JSCell* JSValue::asCell() const - { - ASSERT(isCell()); - return m_ptr; - } -#endif // USE(JSVALUE64) - - inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const - { - return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue(); - } - - inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value) - { - if (isInt32()) { - number = asInt32(); - value = *this; - return true; - } - if (isDouble()) { - number = asDouble(); - value = *this; - return true; - } - if (isCell()) - return asCell()->getPrimitiveNumber(exec, number, value); - if (isTrue()) { - number = 1.0; - value = *this; - return true; - } - if (isFalse() || isNull()) { - number = 0.0; - value = *this; - return true; - } - ASSERT(isUndefined()); - number = nonInlineNaN(); - value = *this; - return true; - } - - inline bool JSValue::toBoolean(ExecState* exec) const - { - if (isInt32()) - return asInt32() != 0; - if (isDouble()) - return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN - if (isCell()) - return asCell()->toBoolean(exec); - return isTrue(); // false, null, and undefined all convert to false. - } - - ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const - { - if (isInt32()) - return asInt32(); - if (isDouble()) - return asDouble(); - if (isCell()) - return asCell()->toNumber(exec); - if (isTrue()) - return 1.0; - return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0. - } - - inline bool JSValue::needsThisConversion() const - { - if (UNLIKELY(!isCell())) - return true; - return asCell()->structure()->typeInfo().needsThisConversion(); - } - - inline JSValue JSValue::getJSNumber() - { - if (isInt32() || isDouble()) - return *this; - if (isCell()) - return asCell()->getJSNumber(); - return JSValue(); - } - - inline JSObject* JSValue::toObject(ExecState* exec) const - { - return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec); - } - - inline JSObject* JSValue::toThisObject(ExecState* exec) const - { - return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec); - } - - ALWAYS_INLINE void MarkStack::append(JSCell* cell) - { - ASSERT(!m_isCheckingForDefaultMarkViolation); - ASSERT(cell); - if (Heap::checkMarkCell(cell)) - return; - if (cell->structure()->typeInfo().type() >= CompoundType) - m_values.append(cell); - } - - ALWAYS_INLINE void MarkStack::append(JSValue value) - { - ASSERT(value); - if (value.isCell()) - append(value.asCell()); - } - - inline Heap* Heap::heap(JSValue v) - { - if (!v.isCell()) - return 0; - return heap(v.asCell()); - } - - inline Heap* Heap::heap(JSCell* c) - { - return cellBlock(c)->heap; - } - -#if ENABLE(JSC_ZOMBIES) - inline bool JSValue::isZombie() const - { - return isCell() && asCell() && asCell()->isZombie(); - } -#endif -} // namespace JSC - -#endif // JSCell_h diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp deleted file mode 100644 index 99f8e6f..0000000 --- a/JavaScriptCore/runtime/JSFunction.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSFunction.h" - -#include "CodeBlock.h" -#include "CommonIdentifiers.h" -#include "CallFrame.h" -#include "ExceptionHelpers.h" -#include "FunctionPrototype.h" -#include "JSGlobalObject.h" -#include "JSNotAnObject.h" -#include "Interpreter.h" -#include "ObjectPrototype.h" -#include "Parser.h" -#include "PropertyNameArray.h" -#include "ScopeChainMark.h" - -using namespace WTF; -using namespace Unicode; - -namespace JSC { -#if ENABLE(JIT) -EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec) -{ - return throwVMError(exec, createNotAConstructorError(exec, exec->callee())); -} -#endif - -ASSERT_CLASS_FITS_IN_CELL(JSFunction); - -const ClassInfo JSFunction::info = { "Function", 0, 0, 0 }; - -bool JSFunction::isHostFunctionNonInline() const -{ - return isHostFunction(); -} - -JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure) - : Base(structure) - , m_executable(adoptRef(new VPtrHackExecutable())) - , m_scopeChain(NoScopeChain()) -{ -} - -#if ENABLE(JIT) -JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, PassRefPtr<NativeExecutable> thunk) - : Base(globalObject, structure) - , m_executable(thunk) - , m_scopeChain(globalObject->globalScopeChain()) -{ - putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); - putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); -} -#endif - -JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func) - : Base(globalObject, structure) -#if ENABLE(JIT) - , m_executable(exec->globalData().getHostFunction(func)) -#endif - , m_scopeChain(globalObject->globalScopeChain()) -{ - putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); -#if ENABLE(JIT) - putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); -#else - UNUSED_PARAM(length); - UNUSED_PARAM(func); - ASSERT_NOT_REACHED(); -#endif -} - -JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode) - : Base(scopeChainNode->globalObject, scopeChainNode->globalObject->functionStructure()) - , m_executable(executable) - , m_scopeChain(scopeChainNode) -{ - const Identifier& name = static_cast<FunctionExecutable*>(m_executable.get())->name(); - putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); -} - -JSFunction::~JSFunction() -{ - ASSERT(vptr() == JSGlobalData::jsFunctionVPtr); - - // 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 (!isHostFunction()) { -#if ENABLE(JIT_OPTIMIZE_CALL) - ASSERT(m_executable); - if (jsExecutable()->isGeneratedForCall()) - jsExecutable()->generatedBytecodeForCall().unlinkCallers(); - if (jsExecutable()->isGeneratedForConstruct()) - jsExecutable()->generatedBytecodeForConstruct().unlinkCallers(); -#endif - } -} - -static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function"; -static const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function"; - -static void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message) -{ - JSValue thrower = createTypeErrorFunction(exec, message); - descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); -} - -const UString& JSFunction::name(ExecState* exec) -{ - return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue(); -} - -const UString JSFunction::displayName(ExecState* exec) -{ - JSValue displayName = getDirect(exec->globalData().propertyNames->displayName); - - if (displayName && isJSString(&exec->globalData(), displayName)) - return asString(displayName)->tryGetValue(); - - return UString(); -} - -const UString JSFunction::calculatedDisplayName(ExecState* exec) -{ - const UString explicitName = displayName(exec); - - if (!explicitName.isEmpty()) - return explicitName; - - return name(exec); -} - -void JSFunction::markChildren(MarkStack& markStack) -{ - Base::markChildren(markStack); - if (!isHostFunction()) { - jsExecutable()->markAggregate(markStack); - scope().markAggregate(markStack); - } -} - -CallType JSFunction::getCallData(CallData& callData) -{ -#if ENABLE(JIT) - if (isHostFunction()) { - callData.native.function = nativeFunction(); - return CallTypeHost; - } -#endif - callData.js.functionExecutable = jsExecutable(); - callData.js.scopeChain = scope().node(); - return CallTypeJS; -} - -JSValue JSFunction::argumentsGetter(ExecState* exec, JSValue slotBase, const Identifier&) -{ - JSFunction* thisObj = asFunction(slotBase); - ASSERT(!thisObj->isHostFunction()); - return exec->interpreter()->retrieveArguments(exec, thisObj); -} - -JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identifier&) -{ - JSFunction* thisObj = asFunction(slotBase); - ASSERT(!thisObj->isHostFunction()); - return exec->interpreter()->retrieveCaller(exec, thisObj); -} - -JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, const Identifier&) -{ - JSFunction* thisObj = asFunction(slotBase); - ASSERT(!thisObj->isHostFunction()); - return jsNumber(thisObj->jsExecutable()->parameterCount()); -} - -bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (isHostFunction()) - return Base::getOwnPropertySlot(exec, propertyName, slot); - - if (propertyName == exec->propertyNames().prototype) { - JSValue* location = getDirectLocation(propertyName); - - if (!location) { - JSObject* prototype = new (exec) JSObject(scope().globalObject()->emptyObjectStructure()); - prototype->putDirect(exec->propertyNames().constructor, this, DontEnum); - putDirect(exec->propertyNames().prototype, prototype, DontDelete | DontEnum); - location = getDirectLocation(propertyName); - } - - slot.setValueSlot(this, location, offsetForLocation(location)); - } - - if (propertyName == exec->propertyNames().arguments) { - if (jsExecutable()->isStrictMode()) { - throwTypeError(exec, "Can't access arguments object of a strict mode function"); - slot.setValue(jsNull()); - return true; - } - - slot.setCacheableCustom(this, argumentsGetter); - return true; - } - - if (propertyName == exec->propertyNames().length) { - slot.setCacheableCustom(this, lengthGetter); - return true; - } - - if (propertyName == exec->propertyNames().caller) { - if (jsExecutable()->isStrictMode()) { - throwTypeError(exec, StrictModeCallerAccessError); - slot.setValue(jsNull()); - return true; - } - slot.setCacheableCustom(this, callerGetter); - return true; - } - - return Base::getOwnPropertySlot(exec, propertyName, slot); -} - -bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (isHostFunction()) - return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); - - if (propertyName == exec->propertyNames().prototype) { - PropertySlot slot; - getOwnPropertySlot(exec, propertyName, slot); - return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); - } - - if (propertyName == exec->propertyNames().arguments) { - if (jsExecutable()->isStrictMode()) - createDescriptorForThrowingProperty(exec, descriptor, StrictModeArgumentsAccessError); - else - descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete); - return true; - } - - if (propertyName == exec->propertyNames().length) { - descriptor.setDescriptor(jsNumber(jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); - return true; - } - - if (propertyName == exec->propertyNames().caller) { - if (jsExecutable()->isStrictMode()) - createDescriptorForThrowingProperty(exec, descriptor, StrictModeCallerAccessError); - else - descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete); - return true; - } - - return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - -void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - if (!isHostFunction() && (mode == IncludeDontEnumProperties)) { - // Make sure prototype has been reified. - PropertySlot slot; - getOwnPropertySlot(exec, exec->propertyNames().prototype, slot); - - propertyNames.add(exec->propertyNames().arguments); - propertyNames.add(exec->propertyNames().callee); - propertyNames.add(exec->propertyNames().caller); - propertyNames.add(exec->propertyNames().length); - } - Base::getOwnPropertyNames(exec, propertyNames, mode); -} - -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().prototype) { - // Make sure prototype has been reified, such that it can only be overwritten - // following the rules set out in ECMA-262 8.12.9. - PropertySlot slot; - getOwnPropertySlot(exec, propertyName, slot); - } - if (jsExecutable()->isStrictMode()) { - if (propertyName == exec->propertyNames().arguments) { - throwTypeError(exec, StrictModeArgumentsAccessError); - return; - } - if (propertyName == exec->propertyNames().caller) { - throwTypeError(exec, StrictModeCallerAccessError); - return; - } - } - if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length) - return; - Base::put(exec, propertyName, value, slot); -} - -bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - if (isHostFunction()) - return Base::deleteProperty(exec, propertyName); - if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length) - return false; - return Base::deleteProperty(exec, propertyName); -} - -// ECMA 13.2.2 [[Construct]] -ConstructType JSFunction::getConstructData(ConstructData& constructData) -{ - if (isHostFunction()) - return ConstructTypeNone; - constructData.js.functionExecutable = jsExecutable(); - constructData.js.scopeChain = scope().node(); - return ConstructTypeJS; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h deleted file mode 100644 index 3a2fe30..0000000 --- a/JavaScriptCore/runtime/JSFunction.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSFunction_h -#define JSFunction_h - -#include "JSObjectWithGlobalObject.h" - -namespace JSC { - - class ExecutableBase; - class FunctionExecutable; - class FunctionPrototype; - class JSActivation; - class JSGlobalObject; - class NativeExecutable; - - EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*); - - class JSFunction : public JSObjectWithGlobalObject { - friend class JIT; - friend class JSGlobalData; - - typedef JSObjectWithGlobalObject Base; - - public: - JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction); -#if ENABLE(JIT) - JSFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, PassRefPtr<NativeExecutable>); -#endif - JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*); - virtual ~JSFunction(); - - const UString& name(ExecState*); - const UString displayName(ExecState*); - const UString calculatedDisplayName(ExecState*); - - ScopeChain& scope() - { - ASSERT(!isHostFunctionNonInline()); - return m_scopeChain; - } - void setScope(const ScopeChain& scopeChain) - { - ASSERT(!isHostFunctionNonInline()); - m_scopeChain = scopeChain; - } - - ExecutableBase* executable() const { return m_executable.get(); } - - // To call either of these methods include Executable.h - inline bool isHostFunction() const; - FunctionExecutable* jsExecutable() const; - - static JS_EXPORTDATA const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - NativeFunction nativeFunction(); - - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - - protected: - const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags; - - private: - JSFunction(NonNullPassRefPtr<Structure>); - - bool isHostFunctionNonInline() const; - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - - virtual void markChildren(MarkStack&); - - virtual const ClassInfo* classInfo() const { return &info; } - - static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&); - static JSValue callerGetter(ExecState*, JSValue, const Identifier&); - static JSValue lengthGetter(ExecState*, JSValue, const Identifier&); - - RefPtr<ExecutableBase> m_executable; - ScopeChain m_scopeChain; - }; - - JSFunction* asFunction(JSValue); - - inline JSFunction* asFunction(JSValue value) - { - ASSERT(asObject(value)->inherits(&JSFunction::info)); - return static_cast<JSFunction*>(asObject(value)); - } - -} // namespace JSC - -#endif // JSFunction_h diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp deleted file mode 100644 index aca995a..0000000 --- a/JavaScriptCore/runtime/JSGlobalData.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "JSGlobalData.h" - -#include "ArgList.h" -#include "Collector.h" -#include "CollectorHeapIterator.h" -#include "CommonIdentifiers.h" -#include "FunctionConstructor.h" -#include "GetterSetter.h" -#include "Interpreter.h" -#include "JSActivation.h" -#include "JSAPIValueWrapper.h" -#include "JSArray.h" -#include "JSByteArray.h" -#include "JSClassRef.h" -#include "JSFunction.h" -#include "JSLock.h" -#include "JSNotAnObject.h" -#include "JSPropertyNameIterator.h" -#include "JSStaticScopeObject.h" -#include "Lexer.h" -#include "Lookup.h" -#include "Nodes.h" -#include "Parser.h" -#include "RegExpCache.h" -#include "StrictEvalActivation.h" -#include <wtf/WTFThreadData.h> -#if ENABLE(REGEXP_TRACING) -#include "RegExp.h" -#endif - - -#if ENABLE(JSC_MULTIPLE_THREADS) -#include <wtf/Threading.h> -#endif - -#if PLATFORM(MAC) -#include "ProfilerServer.h" -#include <CoreFoundation/CoreFoundation.h> -#endif - -using namespace WTF; - -namespace JSC { - -extern JSC_CONST_HASHTABLE HashTable arrayTable; -extern JSC_CONST_HASHTABLE HashTable jsonTable; -extern JSC_CONST_HASHTABLE HashTable dateTable; -extern JSC_CONST_HASHTABLE HashTable mathTable; -extern JSC_CONST_HASHTABLE HashTable numberTable; -extern JSC_CONST_HASHTABLE HashTable regExpTable; -extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable; -extern JSC_CONST_HASHTABLE HashTable stringTable; - -void* JSGlobalData::jsArrayVPtr; -void* JSGlobalData::jsByteArrayVPtr; -void* JSGlobalData::jsStringVPtr; -void* JSGlobalData::jsFunctionVPtr; - -void JSGlobalData::storeVPtrs() -{ - CollectorCell cell; - void* storage = &cell; - - COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell); - JSCell* jsArray = new (storage) JSArray(JSArray::VPtrStealingHack); - JSGlobalData::jsArrayVPtr = jsArray->vptr(); - jsArray->~JSCell(); - - COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell); - JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack); - JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr(); - jsByteArray->~JSCell(); - - COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell); - JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack); - JSGlobalData::jsStringVPtr = jsString->vptr(); - jsString->~JSCell(); - - COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell); - JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull())); - JSGlobalData::jsFunctionVPtr = jsFunction->vptr(); - jsFunction->~JSCell(); -} - -JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType) - : globalDataType(globalDataType) - , clientData(0) - , arrayTable(fastNew<HashTable>(JSC::arrayTable)) - , dateTable(fastNew<HashTable>(JSC::dateTable)) - , jsonTable(fastNew<HashTable>(JSC::jsonTable)) - , mathTable(fastNew<HashTable>(JSC::mathTable)) - , numberTable(fastNew<HashTable>(JSC::numberTable)) - , regExpTable(fastNew<HashTable>(JSC::regExpTable)) - , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable)) - , stringTable(fastNew<HashTable>(JSC::stringTable)) - , activationStructure(JSActivation::createStructure(jsNull())) - , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull())) - , terminatedExecutionErrorStructure(JSObject::createStructure(jsNull())) - , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull())) - , strictEvalActivationStructure(StrictEvalActivation::createStructure(jsNull())) - , stringStructure(JSString::createStructure(jsNull())) - , notAnObjectStructure(JSNotAnObject::createStructure(jsNull())) - , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull())) - , getterSetterStructure(GetterSetter::createStructure(jsNull())) - , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull())) - , dummyMarkableCellStructure(JSCell::createDummyStructure()) - , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable()) - , propertyNames(new CommonIdentifiers(this)) - , emptyList(new MarkedArgumentBuffer) - , lexer(new Lexer(this)) - , parser(new Parser) - , interpreter(new Interpreter) - , heap(this) - , head(0) - , dynamicGlobalObject(0) - , firstStringifierToMark(0) - , markStack(jsArrayVPtr) - , cachedUTCOffset(NaN) - , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth) - , m_regExpCache(new RegExpCache(this)) -#if ENABLE(REGEXP_TRACING) - , m_rtTraceList(new RTTraceList()) -#endif -#ifndef NDEBUG - , exclusiveThread(0) -#endif -{ - if (globalDataType == Default) - m_stack = wtfThreadData().stack(); - -#if PLATFORM(MAC) - startProfilerServerIfNeeded(); -#endif -#if ENABLE(JIT) && ENABLE(INTERPRETER) -#if PLATFORM(CF) - CFStringRef canUseJITKey = CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman); - CFBooleanRef canUseJIT = (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication); - if (canUseJIT) { - m_canUseJIT = kCFBooleanTrue == canUseJIT; - CFRelease(canUseJIT); - } else - m_canUseJIT = !getenv("JavaScriptCoreUseJIT"); - CFRelease(canUseJITKey); -#elif OS(UNIX) - m_canUseJIT = !getenv("JavaScriptCoreUseJIT"); -#else - m_canUseJIT = true; -#endif -#endif -#if ENABLE(JIT) -#if ENABLE(INTERPRETER) - if (m_canUseJIT) - m_canUseJIT = executableAllocator.isValid(); -#endif - jitStubs = new JITThunks(this); -#endif -} - -JSGlobalData::~JSGlobalData() -{ - // By the time this is destroyed, heap.destroy() must already have been called. - - delete interpreter; -#ifndef NDEBUG - // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance. - interpreter = 0; -#endif - - arrayTable->deleteTable(); - dateTable->deleteTable(); - jsonTable->deleteTable(); - mathTable->deleteTable(); - numberTable->deleteTable(); - regExpTable->deleteTable(); - regExpConstructorTable->deleteTable(); - stringTable->deleteTable(); - - fastDelete(const_cast<HashTable*>(arrayTable)); - fastDelete(const_cast<HashTable*>(dateTable)); - fastDelete(const_cast<HashTable*>(jsonTable)); - fastDelete(const_cast<HashTable*>(mathTable)); - fastDelete(const_cast<HashTable*>(numberTable)); - fastDelete(const_cast<HashTable*>(regExpTable)); - fastDelete(const_cast<HashTable*>(regExpConstructorTable)); - fastDelete(const_cast<HashTable*>(stringTable)); - - delete parser; - delete lexer; - - deleteAllValues(opaqueJSClassData); - - delete emptyList; - - delete propertyNames; - if (globalDataType != Default) - deleteIdentifierTable(identifierTable); - - delete clientData; - delete m_regExpCache; -#if ENABLE(REGEXP_TRACING) - delete m_rtTraceList; -#endif -} - -PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type) -{ - return adoptRef(new JSGlobalData(APIContextGroup, type)); -} - -PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type) -{ - return adoptRef(new JSGlobalData(Default, type)); -} - -PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type) -{ - Structure::startIgnoringLeaks(); - RefPtr<JSGlobalData> data = create(type); - Structure::stopIgnoringLeaks(); - return data.release(); -} - -bool JSGlobalData::sharedInstanceExists() -{ - return sharedInstanceInternal(); -} - -JSGlobalData& JSGlobalData::sharedInstance() -{ - JSGlobalData*& instance = sharedInstanceInternal(); - if (!instance) { - instance = adoptRef(new JSGlobalData(APIShared, ThreadStackTypeSmall)).leakRef(); -#if ENABLE(JSC_MULTIPLE_THREADS) - instance->makeUsableFromMultipleThreads(); -#endif - } - return *instance; -} - -JSGlobalData*& JSGlobalData::sharedInstanceInternal() -{ - ASSERT(JSLock::currentThreadIsHoldingLock()); - static JSGlobalData* sharedInstance; - return sharedInstance; -} - -#if ENABLE(JIT) -PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function) -{ - return jitStubs->hostFunctionStub(this, function); -} -PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator) -{ - return jitStubs->hostFunctionStub(this, function, generator); -} -#endif - -JSGlobalData::ClientData::~ClientData() -{ -} - -void JSGlobalData::resetDateCache() -{ - cachedUTCOffset = NaN; - dstOffsetCache.reset(); - cachedDateString = UString(); - cachedDateStringValue = NaN; - dateInstanceCache.reset(); -} - -void JSGlobalData::startSampling() -{ - interpreter->startSampling(); -} - -void JSGlobalData::stopSampling() -{ - interpreter->stopSampling(); -} - -void JSGlobalData::dumpSampleData(ExecState* exec) -{ - interpreter->dumpSampleData(exec); -} - -void JSGlobalData::recompileAllJSFunctions() -{ - // If JavaScript is running, it's not safe to recompile, since we'll end - // up throwing away code that is live on the stack. - ASSERT(!dynamicGlobalObject); - - LiveObjectIterator it = heap.primaryHeapBegin(); - LiveObjectIterator heapEnd = heap.primaryHeapEnd(); - for ( ; it != heapEnd; ++it) { - if ((*it)->inherits(&JSFunction::info)) { - JSFunction* function = asFunction(*it); - if (!function->executable()->isHostFunction()) - function->jsExecutable()->discardCode(); - } - } -} - -#if ENABLE(REGEXP_TRACING) -void JSGlobalData::addRegExpToTrace(PassRefPtr<RegExp> regExp) -{ - m_rtTraceList->add(regExp); -} - -void JSGlobalData::dumpRegExpTrace() -{ - // The first RegExp object is ignored. It is create by the RegExpPrototype ctor and not used. - RTTraceList::iterator iter = ++m_rtTraceList->begin(); - - if (iter != m_rtTraceList->end()) { - printf("\nRegExp Tracing\n"); - printf(" match() matches\n"); - printf("Regular Expression JIT Address calls found\n"); - printf("----------------------------------------+----------------+----------+----------\n"); - - unsigned reCount = 0; - - for (; iter != m_rtTraceList->end(); ++iter, ++reCount) - (*iter)->printTraceData(); - - printf("%d Regular Expressions\n", reCount); - } - - m_rtTraceList->clear(); -} -#else -void JSGlobalData::dumpRegExpTrace() -{ -} -#endif - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h deleted file mode 100644 index 699f975..0000000 --- a/JavaScriptCore/runtime/JSGlobalData.h +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSGlobalData_h -#define JSGlobalData_h - -#include "CachedTranscendentalFunction.h" -#include "Collector.h" -#include "DateInstanceCache.h" -#include "ExecutableAllocator.h" -#include "JITStubs.h" -#include "JSValue.h" -#include "MarkStack.h" -#include "NumericStrings.h" -#include "SmallStrings.h" -#include "Terminator.h" -#include "TimeoutChecker.h" -#include "WeakRandom.h" -#include <wtf/BumpPointerAllocator.h> -#include <wtf/Forward.h> -#include <wtf/HashMap.h> -#include <wtf/RefCounted.h> -#include <wtf/ThreadSpecific.h> -#include <wtf/WTFThreadData.h> -#if ENABLE(REGEXP_TRACING) -#include <wtf/ListHashSet.h> -#endif - -struct OpaqueJSClass; -struct OpaqueJSClassContextData; - -namespace JSC { - - class CodeBlock; - class CommonIdentifiers; - class IdentifierTable; - class Interpreter; - class JSGlobalObject; - class JSObject; - class Lexer; - class Parser; - class RegExpCache; - class Stringifier; - class Structure; - class UString; -#if ENABLE(REGEXP_TRACING) - class RegExp; -#endif - - struct HashTable; - struct Instruction; - - struct DSTOffsetCache { - DSTOffsetCache() - { - reset(); - } - - void reset() - { - offset = 0.0; - start = 0.0; - end = -1.0; - increment = 0.0; - } - - double offset; - double start; - double end; - double increment; - }; - - enum ThreadStackType { - ThreadStackTypeLarge, - ThreadStackTypeSmall - }; - - class JSGlobalData : public RefCounted<JSGlobalData> { - public: - // WebCore has a one-to-one mapping of threads to JSGlobalDatas; - // either create() or createLeaked() should only be called once - // on a thread, this is the 'default' JSGlobalData (it uses the - // thread's default string uniquing table from wtfThreadData). - // API contexts created using the new context group aware interface - // create APIContextGroup objects which require less locking of JSC - // than the old singleton APIShared JSGlobalData created for use by - // the original API. - enum GlobalDataType { Default, APIContextGroup, APIShared }; - - struct ClientData { - virtual ~ClientData() = 0; - }; - - bool isSharedInstance() { return globalDataType == APIShared; } - bool usingAPI() { return globalDataType != Default; } - static bool sharedInstanceExists(); - static JSGlobalData& sharedInstance(); - - static PassRefPtr<JSGlobalData> create(ThreadStackType); - static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType); - static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType); - ~JSGlobalData(); - -#if ENABLE(JSC_MULTIPLE_THREADS) - // Will start tracking threads that use the heap, which is resource-heavy. - void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); } -#endif - - GlobalDataType globalDataType; - ClientData* clientData; - - const HashTable* arrayTable; - const HashTable* dateTable; - const HashTable* jsonTable; - const HashTable* mathTable; - const HashTable* numberTable; - const HashTable* regExpTable; - const HashTable* regExpConstructorTable; - const HashTable* stringTable; - - RefPtr<Structure> activationStructure; - RefPtr<Structure> interruptedExecutionErrorStructure; - RefPtr<Structure> terminatedExecutionErrorStructure; - RefPtr<Structure> staticScopeStructure; - RefPtr<Structure> strictEvalActivationStructure; - RefPtr<Structure> stringStructure; - RefPtr<Structure> notAnObjectStructure; - RefPtr<Structure> propertyNameIteratorStructure; - RefPtr<Structure> getterSetterStructure; - RefPtr<Structure> apiWrapperStructure; - RefPtr<Structure> dummyMarkableCellStructure; - - static void storeVPtrs(); - static JS_EXPORTDATA void* jsArrayVPtr; - static JS_EXPORTDATA void* jsByteArrayVPtr; - static JS_EXPORTDATA void* jsStringVPtr; - static JS_EXPORTDATA void* jsFunctionVPtr; - - IdentifierTable* identifierTable; - CommonIdentifiers* propertyNames; - const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark. - SmallStrings smallStrings; - NumericStrings numericStrings; - DateInstanceCache dateInstanceCache; - -#if ENABLE(ASSEMBLER) - ExecutableAllocator executableAllocator; - ExecutableAllocator regexAllocator; -#endif - -#if !ENABLE(JIT) - bool canUseJIT() { return false; } // interpreter only -#elif !ENABLE(INTERPRETER) - bool canUseJIT() { return true; } // jit only -#else - bool canUseJIT() { return m_canUseJIT; } -#endif - - const StackBounds& stack() - { - return (globalDataType == Default) - ? m_stack - : wtfThreadData().stack(); - } - - Lexer* lexer; - Parser* parser; - Interpreter* interpreter; -#if ENABLE(JIT) - OwnPtr<JITThunks> jitStubs; - MacroAssemblerCodePtr getCTIStub(ThunkGenerator generator) - { - return jitStubs->ctiStub(this, generator); - } - PassRefPtr<NativeExecutable> getHostFunction(NativeFunction function); - PassRefPtr<NativeExecutable> getHostFunction(NativeFunction function, ThunkGenerator generator); -#endif - TimeoutChecker timeoutChecker; - Terminator terminator; - Heap heap; - - JSValue exception; -#if ENABLE(JIT) - ReturnAddressPtr exceptionLocation; -#endif - - HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData; - - JSGlobalObject* head; - JSGlobalObject* dynamicGlobalObject; - - HashSet<JSObject*> arrayVisitedElements; - - Stringifier* firstStringifierToMark; - - MarkStack markStack; - - double cachedUTCOffset; - DSTOffsetCache dstOffsetCache; - - UString cachedDateString; - double cachedDateStringValue; - - int maxReentryDepth; - - RegExpCache* m_regExpCache; - - BumpPointerAllocator m_regexAllocator; - -#if ENABLE(REGEXP_TRACING) - typedef ListHashSet<RefPtr<RegExp> > RTTraceList; - RTTraceList* m_rtTraceList; -#endif - -#ifndef NDEBUG - ThreadIdentifier exclusiveThread; -#endif - - CachedTranscendentalFunction<sin> cachedSin; - - void resetDateCache(); - - void startSampling(); - void stopSampling(); - void dumpSampleData(ExecState* exec); - void recompileAllJSFunctions(); - RegExpCache* regExpCache() { return m_regExpCache; } -#if ENABLE(REGEXP_TRACING) - void addRegExpToTrace(PassRefPtr<RegExp> regExp); -#endif - void dumpRegExpTrace(); - private: - JSGlobalData(GlobalDataType, ThreadStackType); - static JSGlobalData*& sharedInstanceInternal(); - void createNativeThunk(); -#if ENABLE(JIT) && ENABLE(INTERPRETER) - bool m_canUseJIT; -#endif - StackBounds m_stack; - }; - -} // namespace JSC - -#endif // JSGlobalData_h diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp deleted file mode 100644 index 408aea7..0000000 --- a/JavaScriptCore/runtime/JSGlobalObject.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "JSGlobalObject.h" - -#include "JSCallbackConstructor.h" -#include "JSCallbackFunction.h" -#include "JSCallbackObject.h" - -#include "Arguments.h" -#include "ArrayConstructor.h" -#include "ArrayPrototype.h" -#include "BooleanConstructor.h" -#include "BooleanPrototype.h" -#include "CodeBlock.h" -#include "DateConstructor.h" -#include "DatePrototype.h" -#include "ErrorConstructor.h" -#include "ErrorPrototype.h" -#include "FunctionConstructor.h" -#include "FunctionPrototype.h" -#include "GlobalEvalFunction.h" -#include "JSFunction.h" -#include "JSGlobalObjectFunctions.h" -#include "JSLock.h" -#include "JSONObject.h" -#include "Interpreter.h" -#include "MathObject.h" -#include "NativeErrorConstructor.h" -#include "NativeErrorPrototype.h" -#include "NumberConstructor.h" -#include "NumberPrototype.h" -#include "ObjectConstructor.h" -#include "ObjectPrototype.h" -#include "Profiler.h" -#include "PrototypeFunction.h" -#include "RegExpConstructor.h" -#include "RegExpMatchesArray.h" -#include "RegExpObject.h" -#include "RegExpPrototype.h" -#include "ScopeChainMark.h" -#include "StringConstructor.h" -#include "StringPrototype.h" -#include "Debugger.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject); - -// Default number of ticks before a timeout check should be done. -static const int initialTickCountThreshold = 255; - -// Preferred number of milliseconds between each timeout check -static const int preferredScriptCheckTimeInterval = 1000; - -static inline void markIfNeeded(MarkStack& markStack, JSValue v) -{ - if (v) - markStack.append(v); -} - -static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) -{ - if (s) - markIfNeeded(markStack, s->storedPrototype()); -} - -JSGlobalObject::~JSGlobalObject() -{ - ASSERT(JSLock::currentThreadIsHoldingLock()); - - if (d()->debugger) - d()->debugger->detach(this); - - Profiler** profiler = Profiler::enabledProfilerReference(); - if (UNLIKELY(*profiler != 0)) { - (*profiler)->stopProfiling(globalExec(), UString()); - } - - d()->next->d()->prev = d()->prev; - d()->prev->d()->next = d()->next; - JSGlobalObject*& headObject = head(); - if (headObject == this) - headObject = d()->next; - if (headObject == this) - headObject = 0; - - HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); - for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) - (*it)->clearGlobalObject(); - - RegisterFile& registerFile = globalData().interpreter->registerFile(); - if (registerFile.clearGlobalObject(this)) - registerFile.setNumGlobals(0); - d()->destructor(d()); -} - -void JSGlobalObject::init(JSObject* thisValue) -{ - ASSERT(JSLock::currentThreadIsHoldingLock()); - - structure()->disableSpecificFunctionTracking(); - - d()->globalData = Heap::heap(this)->globalData(); - d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue); - - JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.node(), CallFrame::noCaller(), 0, 0); - - if (JSGlobalObject*& headObject = head()) { - d()->prev = headObject; - d()->next = headObject->d()->next; - headObject->d()->next->d()->prev = this; - headObject->d()->next = this; - } else - headObject = d()->next = d()->prev = this; - - d()->debugger = 0; - - d()->profileGroup = 0; - - reset(prototype()); -} - -void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - if (symbolTablePut(propertyName, value)) - return; - JSVariableObject::put(exec, propertyName, value, slot); -} - -void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) -{ - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - if (symbolTablePutWithAttributes(propertyName, value, attributes)) - return; - - JSValue valueBefore = getDirect(propertyName); - PutPropertySlot slot; - JSVariableObject::put(exec, propertyName, value, slot); - if (!valueBefore) { - JSValue valueAfter = getDirect(propertyName); - if (valueAfter) - JSObject::putWithAttributes(exec, propertyName, valueAfter, attributes); - } -} - -void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes) -{ - PropertySlot slot; - if (!symbolTableGet(propertyName, slot)) - JSVariableObject::defineGetter(exec, propertyName, getterFunc, attributes); -} - -void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes) -{ - PropertySlot slot; - if (!symbolTableGet(propertyName, slot)) - JSVariableObject::defineSetter(exec, propertyName, setterFunc, attributes); -} - -static inline JSObject* lastInPrototypeChain(JSObject* object) -{ - JSObject* o = object; - while (o->prototype().isObject()) - o = asObject(o->prototype()); - return o; -} - -void JSGlobalObject::reset(JSValue prototype) -{ - ExecState* exec = JSGlobalObject::globalExec(); - - // Prototypes - - d()->functionPrototype = new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created. - d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype); - d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype); - NativeFunctionWrapper* callFunction = 0; - NativeFunctionWrapper* applyFunction = 0; - d()->functionPrototype->addFunctionProperties(exec, this, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction); - d()->callFunction = callFunction; - d()->applyFunction = applyFunction; - d()->objectPrototype = new (exec) ObjectPrototype(exec, this, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get()); - d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype); - - d()->emptyObjectStructure = d()->objectPrototype->inheritorID(); - - d()->functionStructure = JSFunction::createStructure(d()->functionPrototype); - d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype); - d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype); - d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype); - d()->callbackObjectStructure = JSCallbackObject<JSObjectWithGlobalObject>::createStructure(d()->objectPrototype); - - d()->arrayPrototype = new (exec) ArrayPrototype(this, ArrayPrototype::createStructure(d()->objectPrototype)); - d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype); - d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype); - - d()->stringPrototype = new (exec) StringPrototype(exec, this, StringPrototype::createStructure(d()->objectPrototype)); - d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype); - - d()->booleanPrototype = new (exec) BooleanPrototype(exec, this, BooleanPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get()); - d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype); - - d()->numberPrototype = new (exec) NumberPrototype(exec, this, NumberPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get()); - d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype); - - d()->datePrototype = new (exec) DatePrototype(exec, this, DatePrototype::createStructure(d()->objectPrototype)); - d()->dateStructure = DateInstance::createStructure(d()->datePrototype); - - d()->regExpPrototype = new (exec) RegExpPrototype(exec, this, RegExpPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get()); - d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype); - - d()->methodCallDummy = constructEmptyObject(exec); - - ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, this, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get()); - d()->errorStructure = ErrorInstance::createStructure(errorPrototype); - - // Constructors - - JSCell* objectConstructor = new (exec) ObjectConstructor(exec, this, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get()); - JSCell* functionConstructor = new (exec) FunctionConstructor(exec, this, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype); - JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, this, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get()); - JSCell* stringConstructor = new (exec) StringConstructor(exec, this, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype); - JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, this, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype); - JSCell* numberConstructor = new (exec) NumberConstructor(exec, this, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype); - JSCell* dateConstructor = new (exec) DateConstructor(exec, this, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype); - - d()->regExpConstructor = new (exec) RegExpConstructor(exec, this, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype); - - d()->errorConstructor = new (exec) ErrorConstructor(exec, this, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype); - - RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype); - RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype); - d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError"); - d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError"); - d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError"); - d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError"); - d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError"); - d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError"); - - 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); - - // Set global constructors - - // FIXME: These properties could be handled by a static hash table. - - putDirectFunctionWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor, DontEnum); - putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor, DontEnum); - - // Set global values. - GlobalPropertyInfo staticGlobals[] = { - GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, this, MathObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete), - GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete | ReadOnly), - GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete | ReadOnly), - GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly), - GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(this, JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete) - }; - - addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals)); - - // Set global functions. - - d()->evalFunction = new (exec) GlobalEvalFunction(exec, this, GlobalEvalFunction::createStructure(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this); - putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum); -#ifndef NDEBUG - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, this, 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(JSValue prototype) -{ - setPrototype(prototype); - - JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this); - JSObject* objectPrototype = d()->objectPrototype; - if (oldLastInPrototypeChain != objectPrototype) - oldLastInPrototypeChain->setPrototype(objectPrototype); -} - -void JSGlobalObject::markChildren(MarkStack& markStack) -{ - JSVariableObject::markChildren(markStack); - - HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); - for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) - (*it)->markAggregate(markStack); - - RegisterFile& registerFile = globalData().interpreter->registerFile(); - if (registerFile.globalObject() == this) - registerFile.markGlobals(markStack, &globalData().heap); - - markIfNeeded(markStack, d()->regExpConstructor); - markIfNeeded(markStack, d()->errorConstructor); - markIfNeeded(markStack, d()->evalErrorConstructor); - markIfNeeded(markStack, d()->rangeErrorConstructor); - markIfNeeded(markStack, d()->referenceErrorConstructor); - markIfNeeded(markStack, d()->syntaxErrorConstructor); - markIfNeeded(markStack, d()->typeErrorConstructor); - markIfNeeded(markStack, d()->URIErrorConstructor); - - markIfNeeded(markStack, d()->evalFunction); - markIfNeeded(markStack, d()->callFunction); - markIfNeeded(markStack, d()->applyFunction); - - markIfNeeded(markStack, d()->objectPrototype); - markIfNeeded(markStack, d()->functionPrototype); - markIfNeeded(markStack, d()->arrayPrototype); - markIfNeeded(markStack, d()->booleanPrototype); - markIfNeeded(markStack, d()->stringPrototype); - markIfNeeded(markStack, d()->numberPrototype); - markIfNeeded(markStack, d()->datePrototype); - markIfNeeded(markStack, d()->regExpPrototype); - - markIfNeeded(markStack, d()->methodCallDummy); - - markIfNeeded(markStack, d()->errorStructure); - markIfNeeded(markStack, d()->argumentsStructure); - markIfNeeded(markStack, d()->arrayStructure); - markIfNeeded(markStack, d()->booleanObjectStructure); - markIfNeeded(markStack, d()->callbackConstructorStructure); - markIfNeeded(markStack, d()->callbackFunctionStructure); - markIfNeeded(markStack, d()->callbackObjectStructure); - markIfNeeded(markStack, d()->dateStructure); - markIfNeeded(markStack, d()->emptyObjectStructure); - markIfNeeded(markStack, d()->errorStructure); - markIfNeeded(markStack, d()->functionStructure); - markIfNeeded(markStack, d()->numberObjectStructure); - markIfNeeded(markStack, d()->prototypeFunctionStructure); - markIfNeeded(markStack, d()->regExpMatchesArrayStructure); - markIfNeeded(markStack, d()->regExpStructure); - markIfNeeded(markStack, d()->stringObjectStructure); - - // No need to mark the other structures, because their prototypes are all - // guaranteed to be referenced elsewhere. - - Register* registerArray = d()->registerArray.get(); - if (!registerArray) - return; - - size_t size = d()->registerArraySize; - markStack.appendValues(reinterpret_cast<JSValue*>(registerArray), size); -} - -ExecState* JSGlobalObject::globalExec() -{ - return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize); -} - -bool JSGlobalObject::isDynamicScope(bool&) const -{ - return true; -} - -void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile) -{ - ASSERT(!d()->registerArray); - ASSERT(!d()->registerArraySize); - - int numGlobals = registerFile.numGlobals(); - if (!numGlobals) { - d()->registers = 0; - return; - } - - Register* registerArray = copyRegisterArray(registerFile.lastGlobal(), numGlobals); - setRegisters(registerArray + numGlobals, registerArray, numGlobals); -} - -void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile) -{ - JSGlobalObject* lastGlobalObject = registerFile.globalObject(); - if (lastGlobalObject && lastGlobalObject != this) - lastGlobalObject->copyGlobalsFrom(registerFile); - - registerFile.setGlobalObject(this); - registerFile.setNumGlobals(symbolTable().size()); - - if (d()->registerArray) { - memcpy(registerFile.start() - d()->registerArraySize, d()->registerArray.get(), d()->registerArraySize * sizeof(Register)); - setRegisters(registerFile.start(), 0, 0); - } -} - -void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData) -{ - return globalData->heap.allocate(size); -} - -void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData) -{ - delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData); -} - -DynamicGlobalObjectScope::DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject) - : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject) - , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot) -{ - if (!m_dynamicGlobalObjectSlot) { -#if ENABLE(ASSEMBLER) - if (ExecutableAllocator::underMemoryPressure()) - callFrame->globalData().recompileAllJSFunctions(); -#endif - - m_dynamicGlobalObjectSlot = dynamicGlobalObject; - - // Reset the date cache between JS invocations to force the VM - // to observe time zone changes. - callFrame->globalData().resetDateCache(); - } -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h deleted file mode 100644 index a22b0aa..0000000 --- a/JavaScriptCore/runtime/JSGlobalObject.h +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSGlobalObject_h -#define JSGlobalObject_h - -#include "JSArray.h" -#include "JSGlobalData.h" -#include "JSVariableObject.h" -#include "JSWeakObjectMapRefInternal.h" -#include "NativeFunctionWrapper.h" -#include "NumberPrototype.h" -#include "StringPrototype.h" -#include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/RandomNumber.h> - -namespace JSC { - - class ArrayPrototype; - class BooleanPrototype; - class DatePrototype; - class Debugger; - class ErrorConstructor; - class FunctionPrototype; - class GlobalCodeBlock; - class GlobalEvalFunction; - class NativeErrorConstructor; - class ProgramCodeBlock; - class PrototypeFunction; - class RegExpConstructor; - class RegExpPrototype; - class RegisterFile; - - struct ActivationStackNode; - struct HashTable; - - typedef Vector<ExecState*, 16> ExecStateStack; - - class JSGlobalObject : public JSVariableObject { - protected: - using JSVariableObject::JSVariableObjectData; - typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet; - - struct JSGlobalObjectData : public JSVariableObjectData { - // We use an explicit destructor function pointer instead of a - // virtual destructor because we want to avoid adding a vtable - // pointer to this struct. Adding a vtable pointer would force the - // compiler to emit costly pointer fixup code when casting from - // JSVariableObjectData* to JSGlobalObjectData*. - typedef void (*Destructor)(void*); - - JSGlobalObjectData(Destructor destructor) - : JSVariableObjectData(&symbolTable, 0) - , destructor(destructor) - , registerArraySize(0) - , globalScopeChain(NoScopeChain()) - , regExpConstructor(0) - , errorConstructor(0) - , evalErrorConstructor(0) - , rangeErrorConstructor(0) - , referenceErrorConstructor(0) - , syntaxErrorConstructor(0) - , typeErrorConstructor(0) - , URIErrorConstructor(0) - , evalFunction(0) - , callFunction(0) - , applyFunction(0) - , objectPrototype(0) - , functionPrototype(0) - , arrayPrototype(0) - , booleanPrototype(0) - , stringPrototype(0) - , numberPrototype(0) - , datePrototype(0) - , regExpPrototype(0) - , methodCallDummy(0) - , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) - { - } - - Destructor destructor; - - size_t registerArraySize; - - JSGlobalObject* next; - JSGlobalObject* prev; - - Debugger* debugger; - - ScopeChain globalScopeChain; - Register globalCallFrame[RegisterFile::CallFrameHeaderSize]; - - RegExpConstructor* regExpConstructor; - ErrorConstructor* errorConstructor; - NativeErrorConstructor* evalErrorConstructor; - NativeErrorConstructor* rangeErrorConstructor; - NativeErrorConstructor* referenceErrorConstructor; - NativeErrorConstructor* syntaxErrorConstructor; - NativeErrorConstructor* typeErrorConstructor; - NativeErrorConstructor* URIErrorConstructor; - - GlobalEvalFunction* evalFunction; - NativeFunctionWrapper* callFunction; - NativeFunctionWrapper* applyFunction; - - ObjectPrototype* objectPrototype; - FunctionPrototype* functionPrototype; - ArrayPrototype* arrayPrototype; - BooleanPrototype* booleanPrototype; - StringPrototype* stringPrototype; - NumberPrototype* numberPrototype; - DatePrototype* datePrototype; - RegExpPrototype* regExpPrototype; - - JSObject* methodCallDummy; - - RefPtr<Structure> argumentsStructure; - RefPtr<Structure> arrayStructure; - RefPtr<Structure> booleanObjectStructure; - RefPtr<Structure> callbackConstructorStructure; - RefPtr<Structure> callbackFunctionStructure; - RefPtr<Structure> callbackObjectStructure; - RefPtr<Structure> dateStructure; - RefPtr<Structure> emptyObjectStructure; - RefPtr<Structure> errorStructure; - RefPtr<Structure> functionStructure; - RefPtr<Structure> numberObjectStructure; - RefPtr<Structure> prototypeFunctionStructure; - RefPtr<Structure> regExpMatchesArrayStructure; - RefPtr<Structure> regExpStructure; - RefPtr<Structure> stringObjectStructure; - RefPtr<Structure> internalFunctionStructure; - - SymbolTable symbolTable; - unsigned profileGroup; - - RefPtr<JSGlobalData> globalData; - - HashSet<GlobalCodeBlock*> codeBlocks; - WeakMapSet weakMaps; - WeakRandom weakRandom; - }; - - public: - void* operator new(size_t, JSGlobalData*); - - explicit JSGlobalObject() - : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData)) - { - COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot); - putAnonymousValue(0, this); - init(this); - } - - explicit JSGlobalObject(NonNullPassRefPtr<Structure> structure) - : JSVariableObject(structure, new JSGlobalObjectData(destroyJSGlobalObjectData)) - { - COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot); - putAnonymousValue(0, this); - init(this); - } - - protected: - JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue) - : JSVariableObject(structure, data) - { - COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot); - putAnonymousValue(0, this); - init(thisValue); - } - - public: - virtual ~JSGlobalObject(); - - virtual void markChildren(MarkStack&); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&); - virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); - virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes); - - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes); - - // Linked list of all global objects that use the same JSGlobalData. - JSGlobalObject*& head() { return d()->globalData->head; } - JSGlobalObject* next() { return d()->next; } - - // The following accessors return pristine values, even if a script - // replaces the global object's associated property. - - RegExpConstructor* regExpConstructor() const { return d()->regExpConstructor; } - - ErrorConstructor* errorConstructor() const { return d()->errorConstructor; } - NativeErrorConstructor* evalErrorConstructor() const { return d()->evalErrorConstructor; } - NativeErrorConstructor* rangeErrorConstructor() const { return d()->rangeErrorConstructor; } - NativeErrorConstructor* referenceErrorConstructor() const { return d()->referenceErrorConstructor; } - NativeErrorConstructor* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; } - NativeErrorConstructor* typeErrorConstructor() const { return d()->typeErrorConstructor; } - NativeErrorConstructor* URIErrorConstructor() const { return d()->URIErrorConstructor; } - - GlobalEvalFunction* evalFunction() const { return d()->evalFunction; } - - ObjectPrototype* objectPrototype() const { return d()->objectPrototype; } - FunctionPrototype* functionPrototype() const { return d()->functionPrototype; } - ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; } - BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; } - StringPrototype* stringPrototype() const { return d()->stringPrototype; } - NumberPrototype* numberPrototype() const { return d()->numberPrototype; } - DatePrototype* datePrototype() const { return d()->datePrototype; } - RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; } - - JSObject* methodCallDummy() const { return d()->methodCallDummy; } - - Structure* argumentsStructure() const { return d()->argumentsStructure.get(); } - Structure* arrayStructure() const { return d()->arrayStructure.get(); } - Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); } - Structure* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); } - Structure* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); } - Structure* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); } - Structure* dateStructure() const { return d()->dateStructure.get(); } - Structure* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); } - Structure* errorStructure() const { return d()->errorStructure.get(); } - Structure* functionStructure() const { return d()->functionStructure.get(); } - Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); } - Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); } - Structure* internalFunctionStructure() const { return d()->internalFunctionStructure.get(); } - Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); } - Structure* regExpStructure() const { return d()->regExpStructure.get(); } - Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); } - - void setProfileGroup(unsigned value) { d()->profileGroup = value; } - unsigned profileGroup() const { return d()->profileGroup; } - - Debugger* debugger() const { return d()->debugger; } - void setDebugger(Debugger* debugger) { d()->debugger = debugger; } - - virtual bool supportsProfiling() const { return false; } - virtual bool supportsRichSourceInfo() const { return true; } - - ScopeChain& globalScopeChain() { return d()->globalScopeChain; } - - virtual bool isGlobalObject() const { return true; } - - virtual ExecState* globalExec(); - - virtual bool shouldInterruptScript() const { return true; } - - virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; } - - virtual bool isDynamicScope(bool& requiresDynamicChecks) const; - - HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; } - - void copyGlobalsFrom(RegisterFile&); - void copyGlobalsTo(RegisterFile&); - - void resetPrototype(JSValue prototype); - - JSGlobalData& globalData() const { return *d()->globalData.get(); } - JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - void registerWeakMap(OpaqueJSWeakObjectMap* map) - { - d()->weakMaps.add(map); - } - - void deregisterWeakMap(OpaqueJSWeakObjectMap* map) - { - d()->weakMaps.remove(map); - } - - double weakRandomNumber() { return d()->weakRandom.get(); } - protected: - - static const unsigned AnonymousSlotCount = JSVariableObject::AnonymousSlotCount + 1; - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; - - struct GlobalPropertyInfo { - GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) - : identifier(i) - , value(v) - , attributes(a) - { - } - - const Identifier identifier; - JSValue value; - unsigned attributes; - }; - void addStaticGlobals(GlobalPropertyInfo*, int count); - - private: - static void destroyJSGlobalObjectData(void*); - - // FIXME: Fold reset into init. - void init(JSObject* thisValue); - void reset(JSValue prototype); - - void setRegisters(Register* registers, Register* registerArray, size_t count); - - void* operator new(size_t); // can only be allocated with JSGlobalData - }; - - JSGlobalObject* asGlobalObject(JSValue); - - inline JSGlobalObject* asGlobalObject(JSValue value) - { - ASSERT(asObject(value)->isGlobalObject()); - return static_cast<JSGlobalObject*>(asObject(value)); - } - - inline void JSGlobalObject::setRegisters(Register* registers, Register* registerArray, size_t count) - { - JSVariableObject::setRegisters(registers, registerArray); - d()->registerArraySize = count; - } - - inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count) - { - size_t oldSize = d()->registerArraySize; - size_t newSize = oldSize + count; - Register* registerArray = new Register[newSize]; - if (d()->registerArray) - memcpy(registerArray + count, d()->registerArray.get(), oldSize * sizeof(Register)); - setRegisters(registerArray + newSize, registerArray, newSize); - - for (int i = 0, index = -static_cast<int>(oldSize) - 1; i < count; ++i, --index) { - GlobalPropertyInfo& global = globals[i]; - ASSERT(global.attributes & DontDelete); - SymbolTableEntry newEntry(index, global.attributes); - symbolTable().add(global.identifier.impl(), newEntry); - registerAt(index) = global.value; - } - } - - inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) - { - if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot)) - return true; - return symbolTableGet(propertyName, slot); - } - - inline bool JSGlobalObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) - { - if (symbolTableGet(propertyName, descriptor)) - return true; - return JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); - } - - inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName) - { - PropertySlot slot; - if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot)) - return true; - bool slotIsWriteable; - return symbolTableGet(propertyName, slot, slotIsWriteable); - } - - inline JSValue Structure::prototypeForLookup(ExecState* exec) const - { - if (typeInfo().type() == ObjectType) - return m_prototype; - - ASSERT(typeInfo().type() == StringType); - return exec->lexicalGlobalObject()->stringPrototype(); - } - - inline StructureChain* Structure::prototypeChain(ExecState* exec) const - { - // We cache our prototype chain so our clients can share it. - if (!isValid(exec, m_cachedPrototypeChain.get())) { - JSValue prototype = prototypeForLookup(exec); - m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure()); - } - return m_cachedPrototypeChain.get(); - } - - inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const - { - if (!cachedPrototypeChain) - return false; - - JSValue prototype = prototypeForLookup(exec); - RefPtr<Structure>* cachedStructure = cachedPrototypeChain->head(); - while(*cachedStructure && !prototype.isNull()) { - if (asObject(prototype)->structure() != *cachedStructure) - return false; - ++cachedStructure; - prototype = asObject(prototype)->prototype(); - } - return prototype.isNull() && !*cachedStructure; - } - - inline JSGlobalObject* ExecState::dynamicGlobalObject() - { - if (this == lexicalGlobalObject()->globalExec()) - return lexicalGlobalObject(); - - // For any ExecState that's not a globalExec, the - // dynamic global object must be set since code is running - ASSERT(globalData().dynamicGlobalObject); - return globalData().dynamicGlobalObject; - } - - inline JSObject* constructEmptyObject(ExecState* exec) - { - return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure()); - } - - inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject) - { - return new (exec) JSObject(globalObject->emptyObjectStructure()); - } - - inline JSArray* constructEmptyArray(ExecState* exec) - { - return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure()); - } - - inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject) - { - return new (exec) JSArray(globalObject->arrayStructure()); - } - - inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength) - { - return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength, CreateInitialized); - } - - inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue) - { - MarkedArgumentBuffer values; - values.append(singleItemValue); - return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values); - } - - inline JSArray* constructArray(ExecState* exec, const ArgList& values) - { - return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values); - } - - class DynamicGlobalObjectScope : public Noncopyable { - public: - DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject); - - ~DynamicGlobalObjectScope() - { - m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject; - } - - private: - JSGlobalObject*& m_dynamicGlobalObjectSlot; - JSGlobalObject* m_savedDynamicGlobalObject; - }; - -} // namespace JSC - -#endif // JSGlobalObject_h diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp deleted file mode 100644 index 284806e..0000000 --- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSGlobalObjectFunctions.h" - -#include "CallFrame.h" -#include "GlobalEvalFunction.h" -#include "Interpreter.h" -#include "JSGlobalObject.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "Lexer.h" -#include "LiteralParser.h" -#include "Nodes.h" -#include "Parser.h" -#include "UStringBuilder.h" -#include "dtoa.h" -#include <stdio.h> -#include <stdlib.h> -#include <wtf/ASCIICType.h> -#include <wtf/Assertions.h> -#include <wtf/MathExtras.h> -#include <wtf/StringExtras.h> -#include <wtf/unicode/UTF8.h> - -using namespace WTF; -using namespace Unicode; - -namespace JSC { - -static JSValue encode(ExecState* exec, const char* doNotEscape) -{ - UString str = exec->argument(0).toString(exec); - CString cstr = str.utf8(true); - if (!cstr.data()) - return throwError(exec, createURIError(exec, "String contained an illegal UTF-16 sequence.")); - - JSStringBuilder builder; - const char* p = cstr.data(); - for (size_t k = 0; k < cstr.length(); k++, p++) { - char c = *p; - if (c && strchr(doNotEscape, c)) - builder.append(c); - else { - char tmp[4]; - snprintf(tmp, sizeof(tmp), "%%%02X", static_cast<unsigned char>(c)); - builder.append(tmp); - } - } - return builder.build(exec); -} - -static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict) -{ - JSStringBuilder builder; - UString str = exec->argument(0).toString(exec); - int k = 0; - int len = str.length(); - const UChar* d = str.characters(); - UChar u = 0; - while (k < len) { - const UChar* p = d + k; - UChar c = *p; - if (c == '%') { - int charLen = 0; - if (k <= len - 3 && isASCIIHexDigit(p[1]) && isASCIIHexDigit(p[2])) { - const char b0 = Lexer::convertHex(p[1], p[2]); - const int sequenceLen = UTF8SequenceLength(b0); - if (sequenceLen != 0 && k <= len - sequenceLen * 3) { - charLen = sequenceLen * 3; - char sequence[5]; - sequence[0] = b0; - for (int i = 1; i < sequenceLen; ++i) { - const UChar* q = p + i * 3; - if (q[0] == '%' && isASCIIHexDigit(q[1]) && isASCIIHexDigit(q[2])) - sequence[i] = Lexer::convertHex(q[1], q[2]); - else { - charLen = 0; - break; - } - } - if (charLen != 0) { - sequence[sequenceLen] = 0; - const int character = decodeUTF8Sequence(sequence); - if (character < 0 || character >= 0x110000) - charLen = 0; - else if (character >= 0x10000) { - // Convert to surrogate pair. - builder.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10))); - u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF)); - } else - u = static_cast<UChar>(character); - } - } - } - if (charLen == 0) { - if (strict) - return throwError(exec, createURIError(exec, "URI error")); - // The only case where we don't use "strict" mode is the "unescape" function. - // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE. - if (k <= len - 6 && p[1] == 'u' - && isASCIIHexDigit(p[2]) && isASCIIHexDigit(p[3]) - && isASCIIHexDigit(p[4]) && isASCIIHexDigit(p[5])) { - charLen = 6; - u = Lexer::convertUnicode(p[2], p[3], p[4], p[5]); - } - } - if (charLen && (u == 0 || u >= 128 || !strchr(doNotUnescape, u))) { - c = u; - k += charLen - 1; - } - } - k++; - builder.append(c); - } - return builder.build(exec); -} - -bool isStrWhiteSpace(UChar c) -{ - switch (c) { - // ECMA-262-5th 7.2 & 7.3 - case 0x0009: - case 0x000A: - case 0x000B: - case 0x000C: - case 0x000D: - case 0x0020: - case 0x00A0: - case 0x2028: - case 0x2029: - case 0xFEFF: - return true; - default: - return c > 0xff && isSeparatorSpace(c); - } -} - -static int parseDigit(unsigned short c, int radix) -{ - int digit = -1; - - if (c >= '0' && c <= '9') - digit = c - '0'; - else if (c >= 'A' && c <= 'Z') - digit = c - 'A' + 10; - else if (c >= 'a' && c <= 'z') - digit = c - 'a' + 10; - - if (digit >= radix) - return -1; - return digit; -} - -double parseIntOverflow(const char* s, int length, int radix) -{ - double number = 0.0; - double radixMultiplier = 1.0; - - for (const char* p = s + length - 1; p >= s; p--) { - if (radixMultiplier == Inf) { - if (*p != '0') { - number = Inf; - break; - } - } else { - int digit = parseDigit(*p, radix); - number += digit * radixMultiplier; - } - - radixMultiplier *= radix; - } - - return number; -} - -double parseIntOverflow(const UChar* s, int length, int radix) -{ - double number = 0.0; - double radixMultiplier = 1.0; - - for (const UChar* p = s + length - 1; p >= s; p--) { - if (radixMultiplier == Inf) { - if (*p != '0') { - number = Inf; - break; - } - } else { - int digit = parseDigit(*p, radix); - number += digit * radixMultiplier; - } - - radixMultiplier *= radix; - } - - return number; -} - -static double parseInt(const UString& s, int radix) -{ - int length = s.length(); - const UChar* data = s.characters(); - int p = 0; - - while (p < length && isStrWhiteSpace(data[p])) - ++p; - - double sign = 1; - if (p < length) { - if (data[p] == '+') - ++p; - else if (data[p] == '-') { - sign = -1; - ++p; - } - } - - if ((radix == 0 || radix == 16) && length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X')) { - radix = 16; - p += 2; - } else if (radix == 0) { - if (p < length && data[p] == '0') - radix = 8; - else - radix = 10; - } - - if (radix < 2 || radix > 36) - return NaN; - - int firstDigitPosition = p; - bool sawDigit = false; - double number = 0; - while (p < length) { - int digit = parseDigit(data[p], radix); - if (digit == -1) - break; - sawDigit = true; - number *= radix; - number += digit; - ++p; - } - - if (number >= mantissaOverflowLowerBound) { - if (radix == 10) - number = WTF::strtod(s.substringSharingImpl(firstDigitPosition, p - firstDigitPosition).utf8().data(), 0); - else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) - number = parseIntOverflow(s.substringSharingImpl(firstDigitPosition, p - firstDigitPosition).utf8().data(), p - firstDigitPosition, radix); - } - - if (!sawDigit) - return NaN; - - return sign * number; -} - -static const int SizeOfInfinity = 8; - -static bool isInfinity(const UChar* data, const UChar* end) -{ - return (end - data) >= SizeOfInfinity - && data[0] == 'I' - && data[1] == 'n' - && data[2] == 'f' - && data[3] == 'i' - && data[4] == 'n' - && data[5] == 'i' - && data[6] == 't' - && data[7] == 'y'; -} - -// See ecma-262 9.3.1 -static double jsHexIntegerLiteral(const UChar*& data, const UChar* end) -{ - // Hex number. - data += 2; - const UChar* firstDigitPosition = data; - double number = 0; - while (true) { - number = number * 16 + toASCIIHexValue(*data); - ++data; - if (data == end) - break; - if (!isASCIIHexDigit(*data)) - break; - } - if (number >= mantissaOverflowLowerBound) - number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16); - - return number; -} - -// See ecma-262 9.3.1 -static double jsStrDecimalLiteral(const UChar*& data, const UChar* end) -{ - ASSERT(data < end); - - // Copy the sting into a null-terminated byte buffer, and call strtod. - Vector<char, 32> byteBuffer; - for (const UChar* characters = data; characters < end; ++characters) { - UChar character = *characters; - byteBuffer.append(isASCII(character) ? character : 0); - } - byteBuffer.append(0); - char* endOfNumber; - double number = WTF::strtod(byteBuffer.data(), &endOfNumber); - - // Check if strtod found a number; if so return it. - ptrdiff_t consumed = endOfNumber - byteBuffer.data(); - if (consumed) { - data += consumed; - return number; - } - - // Check for [+-]?Infinity - switch (*data) { - case 'I': - if (isInfinity(data, end)) { - data += SizeOfInfinity; - return Inf; - } - break; - - case '+': - if (isInfinity(data + 1, end)) { - data += SizeOfInfinity + 1; - return Inf; - } - break; - - case '-': - if (isInfinity(data + 1, end)) { - data += SizeOfInfinity + 1; - return -Inf; - } - break; - } - - // Not a number. - return NaN; -} - -// See ecma-262 9.3.1 -double jsToNumber(const UString& s) -{ - unsigned size = s.length(); - - if (size == 1) { - UChar c = s.characters()[0]; - if (isASCIIDigit(c)) - return c - '0'; - if (isStrWhiteSpace(c)) - return 0; - return NaN; - } - - const UChar* data = s.characters(); - const UChar* end = data + size; - - // Skip leading white space. - for (; data < end; ++data) { - if (!isStrWhiteSpace(*data)) - break; - } - - // Empty string. - if (data == end) - return 0.0; - - double number; - if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2])) - number = jsHexIntegerLiteral(data, end); - else - number = jsStrDecimalLiteral(data, end); - - // Allow trailing white space. - for (; data < end; ++data) { - if (!isStrWhiteSpace(*data)) - break; - } - if (data != end) - return NaN; - - return number; -} - -static double parseFloat(const UString& s) -{ - unsigned size = s.length(); - - if (size == 1) { - UChar c = s.characters()[0]; - if (isASCIIDigit(c)) - return c - '0'; - return NaN; - } - - const UChar* data = s.characters(); - const UChar* end = data + size; - - // Skip leading white space. - for (; data < end; ++data) { - if (!isStrWhiteSpace(*data)) - break; - } - - // Empty string. - if (data == end) - return NaN; - - return jsStrDecimalLiteral(data, end); -} - -EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec) -{ - JSObject* thisObject = exec->hostThisValue().toThisObject(exec); - JSObject* unwrappedObject = thisObject->unwrappedObject(); - if (!unwrappedObject->isGlobalObject() || static_cast<JSGlobalObject*>(unwrappedObject)->evalFunction() != exec->callee()) - return throwVMError(exec, createEvalError(exec, "The \"this\" value passed to eval must be the global object from which eval originated")); - - JSValue x = exec->argument(0); - if (!x.isString()) - return JSValue::encode(x); - - UString s = x.toString(exec); - - LiteralParser preparser(exec, s, LiteralParser::NonStrictJSON); - if (JSValue parsedObject = preparser.tryLiteralParse()) - return JSValue::encode(parsedObject); - - RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s), false); - JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node()); - if (error) - return throwVMError(exec, error); - - return JSValue::encode(exec->interpreter()->execute(eval.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node())); -} - -EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec) -{ - JSValue value = exec->argument(0); - int32_t radix = exec->argument(1).toInt32(exec); - - if (radix != 0 && radix != 10) - return JSValue::encode(jsNumber(parseInt(value.toString(exec), radix))); - - if (value.isInt32()) - return JSValue::encode(value); - - if (value.isDouble()) { - double d = value.asDouble(); - if (isfinite(d)) - return JSValue::encode(jsNumber((d > 0) ? floor(d) : ceil(d))); - if (isnan(d) || isinf(d)) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(0)); - } - - return JSValue::encode(jsNumber(parseInt(value.toString(exec), radix))); -} - -EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec) -{ - return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)))); -} - -EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec) -{ - return JSValue::encode(jsBoolean(isnan(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec) -{ - double n = exec->argument(0).toNumber(exec); - return JSValue::encode(jsBoolean(!isnan(n) && !isinf(n))); -} - -EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec) -{ - static const char do_not_unescape_when_decoding_URI[] = - "#$&+,/:;=?@"; - - return JSValue::encode(decode(exec, do_not_unescape_when_decoding_URI, true)); -} - -EncodedJSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec) -{ - return JSValue::encode(decode(exec, "", true)); -} - -EncodedJSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState* exec) -{ - static const char do_not_escape_when_encoding_URI[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "!#$&'()*+,-./:;=?@_~"; - - return JSValue::encode(encode(exec, do_not_escape_when_encoding_URI)); -} - -EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState* exec) -{ - static const char do_not_escape_when_encoding_URI_component[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "!'()*-._~"; - - return JSValue::encode(encode(exec, do_not_escape_when_encoding_URI_component)); -} - -EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) -{ - static const char do_not_escape[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "*+-./@_"; - - JSStringBuilder builder; - UString str = exec->argument(0).toString(exec); - const UChar* c = str.characters(); - for (unsigned k = 0; k < str.length(); k++, c++) { - int u = c[0]; - if (u > 255) { - char tmp[7]; - snprintf(tmp, sizeof(tmp), "%%u%04X", u); - builder.append(tmp); - } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u))) - builder.append(c, 1); - else { - char tmp[4]; - snprintf(tmp, sizeof(tmp), "%%%02X", u); - builder.append(tmp); - } - } - - return JSValue::encode(builder.build(exec)); -} - -EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) -{ - UStringBuilder builder; - UString str = exec->argument(0).toString(exec); - int k = 0; - int len = str.length(); - while (k < len) { - const UChar* c = str.characters() + k; - UChar u; - if (c[0] == '%' && k <= len - 6 && c[1] == 'u') { - if (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) { - u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]); - c = &u; - k += 5; - } - } else if (c[0] == '%' && k <= len - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) { - u = UChar(Lexer::convertHex(c[1], c[2])); - c = &u; - k += 2; - } - k++; - builder.append(*c); - } - - return JSValue::encode(jsString(exec, builder.toUString())); -} - -#ifndef NDEBUG -EncodedJSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec) -{ - CString string = exec->argument(0).toString(exec).utf8(); - puts(string.data()); - return JSValue::encode(jsUndefined()); -} -#endif - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h deleted file mode 100644 index 6dc7343..0000000 --- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSGlobalObjectFunctions_h -#define JSGlobalObjectFunctions_h - -#include "JSValue.h" -#include <wtf/unicode/Unicode.h> - -namespace JSC { - - class ArgList; - class ExecState; - class JSObject; - - // FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there - // is a 0.5% reduction. - - EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState*); - EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState*); -#ifndef NDEBUG - EncodedJSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState*); -#endif - - static const double mantissaOverflowLowerBound = 9007199254740992.0; - double parseIntOverflow(const char*, int length, int radix); - double parseIntOverflow(const UChar*, int length, int radix); - bool isStrWhiteSpace(UChar); - double jsToNumber(const UString& s); - -} // namespace JSC - -#endif // JSGlobalObjectFunctions_h diff --git a/JavaScriptCore/runtime/JSImmediate.cpp b/JavaScriptCore/runtime/JSImmediate.cpp deleted file mode 100644 index 846238d..0000000 --- a/JavaScriptCore/runtime/JSImmediate.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2003-2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSImmediate.h" - -namespace JSC { - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h deleted file mode 100644 index 68ba75c..0000000 --- a/JavaScriptCore/runtime/JSImmediate.h +++ /dev/null @@ -1,568 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSImmediate_h -#define JSImmediate_h - -#if USE(JSVALUE64) - -#include <wtf/Assertions.h> -#include <wtf/AlwaysInline.h> -#include <wtf/MathExtras.h> -#include <wtf/StdLibExtras.h> -#include "JSValue.h" -#include <limits> -#include <limits.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdlib.h> - -namespace JSC { - - class ExecState; - class JSCell; - class JSGlobalData; - class JSObject; - class UString; - - 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); - } - - /* - * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged - * value masquerading as a pointer). The low two bits in a JSValue* are available for type tagging - * because allocator alignment guarantees they will be 00 in cell pointers. - * - * For example, on a 32 bit system: - * - * JSCell*: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 00 - * [ high 30 bits: pointer address ] [ low 2 bits -- always 0 ] - * JSImmediate: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TT - * [ high 30 bits: 'payload' ] [ low 2 bits -- tag ] - * - * Where the bottom two bits are non-zero they either indicate that the immediate is a 31 bit signed - * integer, or they mark the value as being an immediate of a type other than integer, with a secondary - * tag used to indicate the exact type. - * - * Where the lowest bit is set (TT is equal to 01 or 11) the high 31 bits form a 31 bit signed int value. - * Where TT is equal to 10 this indicates this is a type of immediate other than an integer, and the next - * two bits will form an extended tag. - * - * 31 bit signed int: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X1 - * [ high 30 bits of the value ] [ high bit part of value ] - * Other: YYYYYYYYYYYYYYYYYYYYYYYYYYYY ZZ 10 - * [ extended 'payload' ] [ extended tag ] [ tag 'other' ] - * - * Where the first bit of the extended tag is set this flags the value as being a boolean, and the following - * bit would flag the value as undefined. If neither bits are set, the value is null. - * - * Other: YYYYYYYYYYYYYYYYYYYYYYYYYYYY UB 10 - * [ extended 'payload' ] [ undefined | bool ] [ tag 'other' ] - * - * For boolean value the lowest bit in the payload holds the value of the bool, all remaining bits are zero. - * For undefined or null immediates the payload is zero. - * - * Boolean: 000000000000000000000000000V 01 10 - * [ boolean value ] [ bool ] [ tag 'other' ] - * Undefined: 0000000000000000000000000000 10 10 - * [ zero ] [ undefined ] [ tag 'other' ] - * Null: 0000000000000000000000000000 00 10 - * [ zero ] [ zero ] [ tag 'other' ] - */ - - /* - * On 64-bit platforms, we support an alternative encoding form for immediates, if - * USE(JSVALUE64) is defined. When this format is used, double precision - * floating point values may also be encoded as JSImmediates. - * - * The encoding makes use of unused NaN space in the IEEE754 representation. Any value - * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values - * can encode a 51-bit payload. Hardware produced and C-library payloads typically - * have a payload of zero. We assume that non-zero payloads are available to encode - * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are - * all set represents a NaN with a non-zero payload, we can use this space in the NaN - * ranges to encode other values (however there are also other ranges of NaN space that - * could have been selected). This range of NaN space is represented by 64-bit numbers - * begining with the 16-bit hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no - * valid double-precision numbers will begin fall in these ranges. - * - * The scheme we have implemented encodes double precision values by adding 2^48 to the - * 64-bit integer representation of the number. After this manipulation, no encoded - * double-precision value will begin with the pattern 0x0000 or 0xFFFF. - * - * The top 16-bits denote the type of the encoded JSImmediate: - * - * Pointer: 0000:PPPP:PPPP:PPPP - * 0001:****:****:**** - * Double:{ ... - * FFFE:****:****:**** - * Integer: FFFF:0000:IIII:IIII - * - * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. The tag 0x0000 - * denotes a pointer, or another form of tagged immediate. Boolean, null and undefined - * values are encoded in the same manner as the default format. - */ - - class JSImmediate { - private: - friend class JIT; - friend class JSValue; - friend class JSInterfaceJIT; - friend class SpecializedThunkJIT; - 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 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; - static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer - static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther; - - static const intptr_t ExtendedTagMask = 0xC; // extended tag holds a further two bits - static const intptr_t ExtendedTagBitBool = 0x4; - static const intptr_t ExtendedTagBitUndefined = 0x8; - - static const intptr_t FullTagTypeMask = TagMask | ExtendedTagMask; - static const intptr_t FullTagTypeBool = TagBitTypeOther | ExtendedTagBitBool; - static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined; - static const intptr_t FullTagTypeNull = TagBitTypeOther; - - static const int32_t IntegerPayloadShift = 0; - static const int32_t ExtendedPayloadShift = 4; - - static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift; - - static const int32_t signBit = 0x80000000; - - static ALWAYS_INLINE bool isImmediate(JSValue v) - { - return rawValue(v) & TagMask; - } - - static ALWAYS_INLINE bool isNumber(JSValue v) - { - return rawValue(v) & TagTypeNumber; - } - - static ALWAYS_INLINE bool isIntegerNumber(JSValue v) - { - return (rawValue(v) & TagTypeNumber) == TagTypeNumber; - } - - static ALWAYS_INLINE bool isDouble(JSValue v) - { - return isNumber(v) && !isIntegerNumber(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 | TagTypeNumber)) == TagTypeNumber; - } - - static ALWAYS_INLINE bool isBoolean(JSValue v) - { - return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool; - } - - static ALWAYS_INLINE bool isUndefinedOrNull(JSValue v) - { - // Undefined and null share the same value, bar the 'undefined' bit in the extended tag. - return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull; - } - - static JSValue from(char); - static JSValue from(signed char); - static JSValue from(unsigned char); - static JSValue from(short); - static JSValue from(unsigned short); - static JSValue from(int); - static JSValue from(unsigned); - static JSValue from(long); - static JSValue from(unsigned long); - static JSValue from(long long); - static JSValue from(unsigned long long); - static JSValue from(double); - - static ALWAYS_INLINE bool isEitherImmediate(JSValue v1, JSValue v2) - { - return (rawValue(v1) | rawValue(v2)) & TagMask; - } - - static ALWAYS_INLINE bool areBothImmediate(JSValue v1, JSValue v2) - { - return isImmediate(v1) & isImmediate(v2); - } - - static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2) - { - return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber; - } - - static double toDouble(JSValue); - static bool toBoolean(JSValue); - - static bool getUInt32(JSValue, uint32_t&); - static bool getTruncatedInt32(JSValue, int32_t&); - static bool getTruncatedUInt32(JSValue, uint32_t&); - - static int32_t getTruncatedInt32(JSValue); - static uint32_t getTruncatedUInt32(JSValue); - - static JSValue trueImmediate(); - static JSValue falseImmediate(); - static JSValue undefinedImmediate(); - static JSValue nullImmediate(); - static JSValue zeroImmediate(); - static JSValue oneImmediate(); - - private: - static const int minImmediateInt = ((-INT_MAX) - 1); - static const int maxImmediateInt = INT_MAX; - static const unsigned maxImmediateUInt = maxImmediateInt; - - static ALWAYS_INLINE JSValue makeValue(intptr_t integer) - { - return JSValue::makeImmediate(integer); - } - - // With USE(JSVALUE64) 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. - static ALWAYS_INLINE JSValue makeInt(uint32_t value) - { - return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber); - } - - static ALWAYS_INLINE JSValue makeDouble(double value) - { - return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset); - } - - static ALWAYS_INLINE JSValue makeBool(bool b) - { - return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool); - } - - static ALWAYS_INLINE JSValue makeUndefined() - { - return makeValue(FullTagTypeUndefined); - } - - static ALWAYS_INLINE JSValue makeNull() - { - return makeValue(FullTagTypeNull); - } - - template<typename T> - static JSValue fromNumberOutsideIntegerRange(T); - - static ALWAYS_INLINE double doubleValue(JSValue v) - { - return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset); - } - - static ALWAYS_INLINE int32_t intValue(JSValue v) - { - return static_cast<int32_t>(rawValue(v) >> IntegerPayloadShift); - } - - static ALWAYS_INLINE uint32_t uintValue(JSValue v) - { - return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift); - } - - static ALWAYS_INLINE bool boolValue(JSValue v) - { - return rawValue(v) & ExtendedPayloadBitBoolValue; - } - - static ALWAYS_INLINE intptr_t rawValue(JSValue v) - { - return v.immediateValue(); - } - }; - - 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); } - - inline bool doubleToBoolean(double value) - { - return value < 0.0 || value > 0.0; - } - - ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v) - { - ASSERT(isImmediate(v)); - return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate() - : doubleToBoolean(doubleValue(v)) : v == trueImmediate(); - } - - ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v) - { - // FIXME: should probably be asserting isPositiveIntegerNumber here. - ASSERT(isIntegerNumber(v)); - return intValue(v); - } - - template<typename T> - inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value) - { - return makeDouble(static_cast<double>(value)); - } - - ALWAYS_INLINE JSValue JSImmediate::from(char i) - { - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(signed char i) - { - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(unsigned char i) - { - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(short i) - { - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(unsigned short i) - { - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(int i) - { - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(unsigned i) - { - if (i > maxImmediateUInt) - return fromNumberOutsideIntegerRange(i); - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(long i) - { - if ((i < minImmediateInt) | (i > maxImmediateInt)) - return fromNumberOutsideIntegerRange(i); - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(unsigned long i) - { - if (i > maxImmediateUInt) - return fromNumberOutsideIntegerRange(i); - return makeInt(i); - } - - ALWAYS_INLINE JSValue JSImmediate::from(long long i) - { - if ((i < minImmediateInt) | (i > maxImmediateInt)) - return JSValue(); - return makeInt(static_cast<intptr_t>(i)); - } - - ALWAYS_INLINE JSValue JSImmediate::from(unsigned long long i) - { - if (i > maxImmediateUInt) - return fromNumberOutsideIntegerRange(i); - return makeInt(static_cast<intptr_t>(i)); - } - - ALWAYS_INLINE JSValue JSImmediate::from(double d) - { - const int intVal = static_cast<int>(d); - - // Check for data loss from conversion to int. - if (intVal != d || (!intVal && signbit(d))) - return fromNumberOutsideIntegerRange(d); - - return from(intVal); - } - - ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue v) - { - ASSERT(isIntegerNumber(v)); - return intValue(v); - } - - ALWAYS_INLINE double JSImmediate::toDouble(JSValue v) - { - ASSERT(isImmediate(v)); - - if (isIntegerNumber(v)) - return intValue(v); - - if (isNumber(v)) { - ASSERT(isDouble(v)); - return doubleValue(v); - } - - if (rawValue(v) == FullTagTypeUndefined) - return nonInlineNaN(); - - ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate())); - return rawValue(v) >> ExtendedPayloadShift; - } - - ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue v, uint32_t& i) - { - i = uintValue(v); - return isPositiveIntegerNumber(v); - } - - ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue v, int32_t& i) - { - i = intValue(v); - return isIntegerNumber(v); - } - - ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue v, uint32_t& i) - { - return getUInt32(v, i); - } - - inline JSValue::JSValue(JSNullTag) - { - *this = JSImmediate::nullImmediate(); - } - - inline JSValue::JSValue(JSUndefinedTag) - { - *this = JSImmediate::undefinedImmediate(); - } - - inline JSValue::JSValue(JSTrueTag) - { - *this = JSImmediate::trueImmediate(); - } - - inline JSValue::JSValue(JSFalseTag) - { - *this = JSImmediate::falseImmediate(); - } - - inline bool JSValue::isUndefinedOrNull() const - { - return JSImmediate::isUndefinedOrNull(asValue()); - } - - inline bool JSValue::isBoolean() const - { - return JSImmediate::isBoolean(asValue()); - } - - inline bool JSValue::isTrue() const - { - return asValue() == JSImmediate::trueImmediate(); - } - - inline bool JSValue::isFalse() const - { - return asValue() == JSImmediate::falseImmediate(); - } - - inline bool JSValue::getBoolean(bool& v) const - { - if (JSImmediate::isBoolean(asValue())) { - v = JSImmediate::toBoolean(asValue()); - return true; - } - - return false; - } - - inline bool JSValue::getBoolean() const - { - return asValue() == jsBoolean(true); - } - - inline bool JSValue::isCell() const - { - return !JSImmediate::isImmediate(asValue()); - } - - inline bool JSValue::isInt32() const - { - return JSImmediate::isIntegerNumber(asValue()); - } - - inline int32_t JSValue::asInt32() const - { - ASSERT(isInt32()); - return JSImmediate::getTruncatedInt32(asValue()); - } - - inline bool JSValue::isUInt32() const - { - return JSImmediate::isPositiveIntegerNumber(asValue()); - } - - inline uint32_t JSValue::asUInt32() const - { - ASSERT(isUInt32()); - return JSImmediate::getTruncatedUInt32(asValue()); - } - -} // namespace JSC - -#endif // USE(JSVALUE64) - -#endif // JSImmediate_h diff --git a/JavaScriptCore/runtime/JSLock.cpp b/JavaScriptCore/runtime/JSLock.cpp deleted file mode 100644 index 10f4f3f..0000000 --- a/JavaScriptCore/runtime/JSLock.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2005, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the NU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - * - */ - -#include "config.h" -#include "JSLock.h" - -#include "Collector.h" -#include "CallFrame.h" - -#if ENABLE(JSC_MULTIPLE_THREADS) -#include <pthread.h> -#endif - -namespace JSC { - -#if ENABLE(JSC_MULTIPLE_THREADS) - -// Acquire this mutex before accessing lock-related data. -static pthread_mutex_t JSMutex = PTHREAD_MUTEX_INITIALIZER; - -// Thread-specific key that tells whether a thread holds the JSMutex, and how many times it was taken recursively. -pthread_key_t JSLockCount; - -static void createJSLockCount() -{ - pthread_key_create(&JSLockCount, 0); -} - -pthread_once_t createJSLockCountOnce = PTHREAD_ONCE_INIT; - -// Lock nesting count. -intptr_t JSLock::lockCount() -{ - pthread_once(&createJSLockCountOnce, createJSLockCount); - - return reinterpret_cast<intptr_t>(pthread_getspecific(JSLockCount)); -} - -static void setLockCount(intptr_t count) -{ - ASSERT(count >= 0); - pthread_setspecific(JSLockCount, reinterpret_cast<void*>(count)); -} - -JSLock::JSLock(ExecState* exec) - : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly) -{ - lock(m_lockBehavior); -} - -JSLock::JSLock(JSGlobalData* globalData) - : m_lockBehavior(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly) -{ - lock(m_lockBehavior); -} - -void JSLock::lock(JSLockBehavior lockBehavior) -{ -#ifdef NDEBUG - // Locking "not for real" is a debug-only feature. - if (lockBehavior == SilenceAssertionsOnly) - return; -#endif - - pthread_once(&createJSLockCountOnce, createJSLockCount); - - intptr_t currentLockCount = lockCount(); - if (!currentLockCount && lockBehavior == LockForReal) { - int result; - result = pthread_mutex_lock(&JSMutex); - ASSERT(!result); - } - setLockCount(currentLockCount + 1); -} - -void JSLock::unlock(JSLockBehavior lockBehavior) -{ - ASSERT(lockCount()); - -#ifdef NDEBUG - // Locking "not for real" is a debug-only feature. - if (lockBehavior == SilenceAssertionsOnly) - return; -#endif - - intptr_t newLockCount = lockCount() - 1; - setLockCount(newLockCount); - if (!newLockCount && lockBehavior == LockForReal) { - int result; - result = pthread_mutex_unlock(&JSMutex); - ASSERT(!result); - } -} - -void JSLock::lock(ExecState* exec) -{ - lock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly); -} - -void JSLock::unlock(ExecState* exec) -{ - unlock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly); -} - -bool JSLock::currentThreadIsHoldingLock() -{ - pthread_once(&createJSLockCountOnce, createJSLockCount); - return !!pthread_getspecific(JSLockCount); -} - -// This is fairly nasty. We allow multiple threads to run on the same -// context, and we do not require any locking semantics in doing so - -// clients of the API may simply use the context from multiple threads -// concurently, and assume this will work. In order to make this work, -// We lock the context when a thread enters, and unlock it when it leaves. -// However we do not only unlock when the thread returns from its -// entry point (evaluate script or call function), we also unlock the -// context if the thread leaves JSC by making a call out to an external -// function through a callback. -// -// All threads using the context share the same JS stack (the RegisterFile). -// Whenever a thread calls into JSC it starts using the RegisterFile from the -// previous 'high water mark' - the maximum point the stack has ever grown to -// (returned by RegisterFile::end()). So if a first thread calls out to a -// callback, and a second thread enters JSC, then also exits by calling out -// to a callback, we can be left with stackframes from both threads in the -// RegisterFile. As such, a problem may occur should the first thread's -// callback complete first, and attempt to return to JSC. Were we to allow -// this to happen, and were its stack to grow further, then it may potentially -// write over the second thread's call frames. -// -// In avoid JS stack corruption we enforce a policy of only ever allowing two -// threads to use a JS context concurrently, and only allowing the second of -// these threads to execute until it has completed and fully returned from its -// outermost call into JSC. We enforce this policy using 'lockDropDepth'. The -// first time a thread exits it will call DropAllLocks - which will do as expected -// and drop locks allowing another thread to enter. Should another thread, or the -// same thread again, enter JSC (through evaluate script or call function), and exit -// again through a callback, then the locks will not be dropped when DropAllLocks -// is called (since lockDropDepth is non-zero). Since this thread is still holding -// the locks, only it will re able to re-enter JSC (either be returning from the -// callback, or by re-entering through another call to evaulate script or call -// function). -// -// This policy is slightly more restricive than it needs to be for correctness - -// we could validly allow futher entries into JSC from other threads, we only -// need ensure that callbacks return in the reverse chronological order of the -// order in which they were made - though implementing the less restrictive policy -// would likely increase complexity and overhead. -// -static unsigned lockDropDepth = 0; - -JSLock::DropAllLocks::DropAllLocks(ExecState* exec) - : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly) -{ - pthread_once(&createJSLockCountOnce, createJSLockCount); - - if (lockDropDepth++) { - m_lockCount = 0; - return; - } - - m_lockCount = JSLock::lockCount(); - for (intptr_t i = 0; i < m_lockCount; i++) - JSLock::unlock(m_lockBehavior); -} - -JSLock::DropAllLocks::DropAllLocks(JSLockBehavior JSLockBehavior) - : m_lockBehavior(JSLockBehavior) -{ - pthread_once(&createJSLockCountOnce, createJSLockCount); - - if (lockDropDepth++) { - m_lockCount = 0; - return; - } - - // It is necessary to drop even "unreal" locks, because having a non-zero lock count - // will prevent a real lock from being taken. - - m_lockCount = JSLock::lockCount(); - for (intptr_t i = 0; i < m_lockCount; i++) - JSLock::unlock(m_lockBehavior); -} - -JSLock::DropAllLocks::~DropAllLocks() -{ - for (intptr_t i = 0; i < m_lockCount; i++) - JSLock::lock(m_lockBehavior); - - --lockDropDepth; -} - -#else - -JSLock::JSLock(ExecState*) - : m_lockBehavior(SilenceAssertionsOnly) -{ -} - -// If threading support is off, set the lock count to a constant value of 1 so ssertions -// that the lock is held don't fail -intptr_t JSLock::lockCount() -{ - return 1; -} - -bool JSLock::currentThreadIsHoldingLock() -{ - return true; -} - -void JSLock::lock(JSLockBehavior) -{ -} - -void JSLock::unlock(JSLockBehavior) -{ -} - -void JSLock::lock(ExecState*) -{ -} - -void JSLock::unlock(ExecState*) -{ -} - -JSLock::DropAllLocks::DropAllLocks(ExecState*) -{ -} - -JSLock::DropAllLocks::DropAllLocks(JSLockBehavior) -{ -} - -JSLock::DropAllLocks::~DropAllLocks() -{ -} - -#endif // USE(MULTIPLE_THREADS) - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSLock.h b/JavaScriptCore/runtime/JSLock.h deleted file mode 100644 index 05b388c..0000000 --- a/JavaScriptCore/runtime/JSLock.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2005, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSLock_h -#define JSLock_h - -#include <wtf/Assertions.h> -#include <wtf/Noncopyable.h> - -namespace JSC { - - // To make it safe to use JavaScript on multiple threads, it is - // important to lock before doing anything that allocates a - // JavaScript data structure or that interacts with shared state - // such as the protect count hash table. The simplest way to lock - // is to create a local JSLock object in the scope where the lock - // must be held. The lock is recursive so nesting is ok. The JSLock - // object also acts as a convenience short-hand for running important - // initialization routines. - - // To avoid deadlock, sometimes it is necessary to temporarily - // release the lock. Since it is recursive you actually have to - // release all locks held by your thread. This is safe to do if - // you are executing code that doesn't require the lock, and you - // reacquire the right number of locks at the end. You can do this - // by constructing a locally scoped JSLock::DropAllLocks object. The - // DropAllLocks object takes care to release the JSLock only if your - // thread acquired it to begin with. - - // For contexts other than the single shared one, implicit locking is not done, - // but we still need to perform all the counting in order to keep debug - // assertions working, so that clients that use the shared context don't break. - - class ExecState; - class JSGlobalData; - - enum JSLockBehavior { SilenceAssertionsOnly, LockForReal }; - - class JSLock : public Noncopyable { - public: - JSLock(ExecState*); - JSLock(JSGlobalData*); - - JSLock(JSLockBehavior lockBehavior) - : m_lockBehavior(lockBehavior) - { -#ifdef NDEBUG - // Locking "not for real" is a debug-only feature. - if (lockBehavior == SilenceAssertionsOnly) - return; -#endif - lock(lockBehavior); - } - - ~JSLock() - { -#ifdef NDEBUG - // Locking "not for real" is a debug-only feature. - if (m_lockBehavior == SilenceAssertionsOnly) - return; -#endif - unlock(m_lockBehavior); - } - - static void lock(JSLockBehavior); - static void unlock(JSLockBehavior); - static void lock(ExecState*); - static void unlock(ExecState*); - - static intptr_t lockCount(); - static bool currentThreadIsHoldingLock(); - - JSLockBehavior m_lockBehavior; - - class DropAllLocks : public Noncopyable { - public: - DropAllLocks(ExecState* exec); - DropAllLocks(JSLockBehavior); - ~DropAllLocks(); - - private: - intptr_t m_lockCount; - JSLockBehavior m_lockBehavior; - }; - }; - -} // namespace - -#endif // JSLock_h diff --git a/JavaScriptCore/runtime/JSNotAnObject.cpp b/JavaScriptCore/runtime/JSNotAnObject.cpp deleted file mode 100644 index e01b401..0000000 --- a/JavaScriptCore/runtime/JSNotAnObject.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "config.h" -#include "JSNotAnObject.h" - -#include <wtf/UnusedParam.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject); - -// JSValue methods -JSValue JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const -{ - ASSERT_UNUSED(exec, exec->hadException()); - return jsNumber(0); -} - -bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue&) -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -bool JSNotAnObject::toBoolean(ExecState* exec) const -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -double JSNotAnObject::toNumber(ExecState* exec) const -{ - ASSERT_UNUSED(exec, exec->hadException()); - return NaN; -} - -UString JSNotAnObject::toString(ExecState* exec) const -{ - ASSERT_UNUSED(exec, exec->hadException()); - return ""; -} - -JSObject* JSNotAnObject::toObject(ExecState* exec) const -{ - ASSERT_UNUSED(exec, exec->hadException()); - return const_cast<JSNotAnObject*>(this); -} - -// JSObject methods -bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, const Identifier&, PropertySlot&) -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&) -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -bool JSNotAnObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier&, PropertyDescriptor&) -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue, PutPropertySlot&) -{ - ASSERT_UNUSED(exec, exec->hadException()); -} - -void JSNotAnObject::put(ExecState* exec, unsigned, JSValue) -{ - ASSERT_UNUSED(exec, exec->hadException()); -} - -bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier&) -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned) -{ - ASSERT_UNUSED(exec, exec->hadException()); - return false; -} - -void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&, EnumerationMode) -{ - ASSERT_UNUSED(exec, exec->hadException()); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSNotAnObject.h b/JavaScriptCore/runtime/JSNotAnObject.h deleted file mode 100644 index 9f527cf..0000000 --- a/JavaScriptCore/runtime/JSNotAnObject.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSNotAnObject_h -#define JSNotAnObject_h - -#include "JSObject.h" - -namespace JSC { - - // This unholy class is used to allow us to avoid multiple exception checks - // in certain SquirrelFish bytecodes -- effectively it just silently consumes - // any operations performed on the result of a failed toObject call. - class JSNotAnObject : public JSObject { - public: - JSNotAnObject(ExecState* exec) - : JSObject(exec->globalData().notAnObjectStructure) - { - } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - private: - - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags; - - // JSValue methods - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&); - virtual bool toBoolean(ExecState*) const; - virtual double toNumber(ExecState*) const; - virtual UString toString(ExecState*) const; - virtual JSObject* toObject(ExecState*) const; - - // JSObject methods - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual void put(ExecState*, unsigned propertyName, JSValue); - - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual bool deleteProperty(ExecState*, unsigned propertyName); - - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - }; - -} // namespace JSC - -#endif // JSNotAnObject_h diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp deleted file mode 100644 index 6fa6b2a..0000000 --- a/JavaScriptCore/runtime/JSNumberCell.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSNumberCell.h" - -// Keep our exported symbols lists happy. -namespace JSC { - -JSValue jsNumberCell(ExecState*, double); - -JSValue jsNumberCell(ExecState*, double) -{ - ASSERT_NOT_REACHED(); - return JSValue(); -} - -} // namespace JSC - diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h deleted file mode 100644 index 0040067..0000000 --- a/JavaScriptCore/runtime/JSNumberCell.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSNumberCell_h -#define JSNumberCell_h - -#include "CallFrame.h" -#include "JSCell.h" -#include "JSImmediate.h" -#include "Collector.h" -#include "UString.h" -#include <stddef.h> // for size_t - -namespace JSC { - - extern const double NaN; - extern const double Inf; - -#if USE(JSVALUE64) - ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d) - { - *this = JSImmediate::fromNumberOutsideIntegerRange(d); - } - - inline JSValue::JSValue(double d) - { - JSValue v = JSImmediate::from(d); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(int i) - { - JSValue v = JSImmediate::from(i); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(unsigned i) - { - JSValue v = JSImmediate::from(i); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(long i) - { - JSValue v = JSImmediate::from(i); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(unsigned long i) - { - JSValue v = JSImmediate::from(i); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(long long i) - { - JSValue v = JSImmediate::from(static_cast<double>(i)); - ASSERT(v); - *this = v; - } - - inline JSValue::JSValue(unsigned long long i) - { - JSValue v = JSImmediate::from(static_cast<double>(i)); - ASSERT(v); - *this = v; - } - - inline bool JSValue::isDouble() const - { - return JSImmediate::isDouble(asValue()); - } - - inline double JSValue::asDouble() const - { - return JSImmediate::doubleValue(asValue()); - } - - inline bool JSValue::isNumber() const - { - return JSImmediate::isNumber(asValue()); - } - - inline double JSValue::uncheckedGetNumber() const - { - ASSERT(isNumber()); - return JSImmediate::toDouble(asValue()); - } - -#endif // USE(JSVALUE64) - -#if USE(JSVALUE64) - - inline JSValue::JSValue(char i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue::JSValue(unsigned char i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue::JSValue(short i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue::JSValue(unsigned short i) - { - ASSERT(JSImmediate::from(i)); - *this = JSImmediate::from(i); - } - - inline JSValue jsNaN() - { - return jsNumber(NaN); - } - - // --- JSValue inlines ---------------------------- - - ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const - { - return isNumber() ? asValue() : jsNumber(this->toNumber(exec)); - } - - inline bool JSValue::getNumber(double &result) const - { - if (isInt32()) - result = asInt32(); - else if (LIKELY(isDouble())) - result = asDouble(); - else { - ASSERT(!isNumber()); - return false; - } - return true; - } - -#endif // USE(JSVALUE64) - -} // namespace JSC - -#endif // JSNumberCell_h diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp deleted file mode 100644 index b5477a1..0000000 --- a/JavaScriptCore/runtime/JSONObject.cpp +++ /dev/null @@ -1,877 +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. - */ - -#include "config.h" -#include "JSONObject.h" - -#include "BooleanObject.h" -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSArray.h" -#include "JSGlobalObject.h" -#include "LiteralParser.h" -#include "Lookup.h" -#include "PropertyNameArray.h" -#include "UStringBuilder.h" -#include "UStringConcatenate.h" -#include <wtf/MathExtras.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSONObject); - -static EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*); -static EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*); - -} - -#include "JSONObject.lut.h" - -namespace JSC { - -JSONObject::JSONObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : JSObjectWithGlobalObject(globalObject, structure) -{ -} - -// PropertyNameForFunctionCall objects must be on the stack, since the JSValue that they create is not marked. -class PropertyNameForFunctionCall { -public: - PropertyNameForFunctionCall(const Identifier&); - PropertyNameForFunctionCall(unsigned); - - JSValue value(ExecState*) const; - -private: - const Identifier* m_identifier; - unsigned m_number; - mutable JSValue m_value; -}; - -class Stringifier : public Noncopyable { -public: - Stringifier(ExecState*, JSValue replacer, JSValue space); - ~Stringifier(); - JSValue stringify(JSValue); - - void markAggregate(MarkStack&); - -private: - class Holder { - public: - Holder(JSObject*); - - JSObject* object() const { return m_object; } - - bool appendNextProperty(Stringifier&, UStringBuilder&); - - private: - JSObject* const m_object; - const bool m_isArray; - bool m_isJSArray; - unsigned m_index; - unsigned m_size; - RefPtr<PropertyNameArrayData> m_propertyNames; - }; - - friend class Holder; - - static void appendQuotedString(UStringBuilder&, const UString&); - - JSValue toJSON(JSValue, const PropertyNameForFunctionCall&); - - enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue }; - StringifyResult appendStringifiedValue(UStringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&); - - bool willIndent() const; - void indent(); - void unindent(); - void startNewLine(UStringBuilder&) const; - - Stringifier* const m_nextStringifierToMark; - ExecState* const m_exec; - const JSValue m_replacer; - bool m_usingArrayReplacer; - PropertyNameArray m_arrayReplacerPropertyNames; - CallType m_replacerCallType; - CallData m_replacerCallData; - const UString m_gap; - - HashSet<JSObject*> m_holderCycleDetector; - Vector<Holder, 16> m_holderStack; - UString m_repeatedGap; - UString m_indent; -}; - -// ------------------------------ helper functions -------------------------------- - -static inline JSValue unwrapBoxedPrimitive(ExecState* exec, JSValue value) -{ - if (!value.isObject()) - return value; - JSObject* object = asObject(value); - if (object->inherits(&NumberObject::info)) - return jsNumber(object->toNumber(exec)); - if (object->inherits(&StringObject::info)) - return jsString(exec, object->toString(exec)); - if (object->inherits(&BooleanObject::info)) - return object->toPrimitive(exec); - return value; -} - -static inline UString gap(ExecState* exec, JSValue space) -{ - const unsigned maxGapLength = 10; - space = unwrapBoxedPrimitive(exec, space); - - // If the space value is a number, create a gap string with that number of spaces. - double spaceCount; - if (space.getNumber(spaceCount)) { - int count; - if (spaceCount > maxGapLength) - count = maxGapLength; - else if (!(spaceCount > 0)) - count = 0; - else - count = static_cast<int>(spaceCount); - UChar spaces[maxGapLength]; - for (int i = 0; i < count; ++i) - spaces[i] = ' '; - return UString(spaces, count); - } - - // If the space value is a string, use it as the gap string, otherwise use no gap string. - UString spaces = space.getString(exec); - if (spaces.length() > maxGapLength) { - spaces = spaces.substringSharingImpl(0, maxGapLength); - } - return spaces; -} - -// ------------------------------ PropertyNameForFunctionCall -------------------------------- - -inline PropertyNameForFunctionCall::PropertyNameForFunctionCall(const Identifier& identifier) - : m_identifier(&identifier) -{ -} - -inline PropertyNameForFunctionCall::PropertyNameForFunctionCall(unsigned number) - : m_identifier(0) - , m_number(number) -{ -} - -JSValue PropertyNameForFunctionCall::value(ExecState* exec) const -{ - if (!m_value) { - if (m_identifier) - m_value = jsString(exec, m_identifier->ustring()); - else - m_value = jsNumber(m_number); - } - return m_value; -} - -// ------------------------------ Stringifier -------------------------------- - -Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space) - : m_nextStringifierToMark(exec->globalData().firstStringifierToMark) - , m_exec(exec) - , m_replacer(replacer) - , m_usingArrayReplacer(false) - , m_arrayReplacerPropertyNames(exec) - , m_replacerCallType(CallTypeNone) - , m_gap(gap(exec, space)) -{ - exec->globalData().firstStringifierToMark = this; - - if (!m_replacer.isObject()) - return; - - if (asObject(m_replacer)->inherits(&JSArray::info)) { - m_usingArrayReplacer = true; - JSObject* array = asObject(m_replacer); - unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec); - for (unsigned i = 0; i < length; ++i) { - JSValue name = array->get(exec, i); - if (exec->hadException()) - break; - - UString propertyName; - if (name.getString(exec, propertyName)) { - m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); - continue; - } - - double value = 0; - if (name.getNumber(value)) { - m_arrayReplacerPropertyNames.add(Identifier::from(exec, value)); - continue; - } - - if (name.isObject()) { - if (!asObject(name)->inherits(&NumberObject::info) && !asObject(name)->inherits(&StringObject::info)) - continue; - propertyName = name.toString(exec); - if (exec->hadException()) - break; - m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName)); - } - } - return; - } - - m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData); -} - -Stringifier::~Stringifier() -{ - ASSERT(m_exec->globalData().firstStringifierToMark == this); - m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark; -} - -void Stringifier::markAggregate(MarkStack& markStack) -{ - for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) { - size_t size = m_holderStack.size(); - for (size_t i = 0; i < size; ++i) - markStack.append(m_holderStack[i].object()); - } -} - -JSValue Stringifier::stringify(JSValue value) -{ - JSObject* object = constructEmptyObject(m_exec); - if (m_exec->hadException()) - return jsNull(); - - PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier); - object->putDirect(m_exec->globalData().propertyNames->emptyIdentifier, value); - - UStringBuilder result; - if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded) - return jsUndefined(); - if (m_exec->hadException()) - return jsNull(); - - return jsString(m_exec, result.toUString()); -} - -void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& value) -{ - int length = value.length(); - - // String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters. - builder.reserveCapacity(builder.length() + length + 2 + 8); - - builder.append('"'); - - const UChar* data = value.characters(); - for (int i = 0; i < length; ++i) { - int start = i; - while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\')) - ++i; - builder.append(data + start, i - start); - if (i >= length) - break; - switch (data[i]) { - case '\t': - builder.append('\\'); - builder.append('t'); - break; - case '\r': - builder.append('\\'); - builder.append('r'); - break; - case '\n': - builder.append('\\'); - builder.append('n'); - break; - case '\f': - builder.append('\\'); - builder.append('f'); - break; - case '\b': - builder.append('\\'); - builder.append('b'); - break; - case '"': - builder.append('\\'); - builder.append('"'); - break; - case '\\': - builder.append('\\'); - builder.append('\\'); - break; - default: - static const char hexDigits[] = "0123456789abcdef"; - UChar ch = data[i]; - UChar hex[] = { '\\', 'u', hexDigits[(ch >> 12) & 0xF], hexDigits[(ch >> 8) & 0xF], hexDigits[(ch >> 4) & 0xF], hexDigits[ch & 0xF] }; - builder.append(hex, WTF_ARRAY_LENGTH(hex)); - break; - } - } - - builder.append('"'); -} - -inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName) -{ - ASSERT(!m_exec->hadException()); - if (!value.isObject() || !asObject(value)->hasProperty(m_exec, m_exec->globalData().propertyNames->toJSON)) - return value; - - JSValue toJSONFunction = asObject(value)->get(m_exec, m_exec->globalData().propertyNames->toJSON); - if (m_exec->hadException()) - return jsNull(); - - if (!toJSONFunction.isObject()) - return value; - - JSObject* object = asObject(toJSONFunction); - CallData callData; - CallType callType = object->getCallData(callData); - if (callType == CallTypeNone) - return value; - - JSValue list[] = { propertyName.value(m_exec) }; - ArgList args(list, WTF_ARRAY_LENGTH(list)); - return call(m_exec, object, callType, callData, value, args); -} - -Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName) -{ - // Call the toJSON function. - value = toJSON(value, propertyName); - if (m_exec->hadException()) - return StringifyFailed; - - // Call the replacer function. - if (m_replacerCallType != CallTypeNone) { - JSValue list[] = { propertyName.value(m_exec), value }; - ArgList args(list, WTF_ARRAY_LENGTH(list)); - value = call(m_exec, m_replacer, m_replacerCallType, m_replacerCallData, holder, args); - if (m_exec->hadException()) - return StringifyFailed; - } - - if (value.isUndefined() && !holder->inherits(&JSArray::info)) - return StringifyFailedDueToUndefinedValue; - - if (value.isNull()) { - builder.append("null"); - return StringifySucceeded; - } - - value = unwrapBoxedPrimitive(m_exec, value); - - if (m_exec->hadException()) - return StringifyFailed; - - if (value.isBoolean()) { - builder.append(value.getBoolean() ? "true" : "false"); - return StringifySucceeded; - } - - UString stringValue; - if (value.getString(m_exec, stringValue)) { - appendQuotedString(builder, stringValue); - return StringifySucceeded; - } - - double numericValue; - if (value.getNumber(numericValue)) { - if (!isfinite(numericValue)) - builder.append("null"); - else - builder.append(UString::number(numericValue)); - return StringifySucceeded; - } - - if (!value.isObject()) - return StringifyFailed; - - JSObject* object = asObject(value); - - CallData callData; - if (object->getCallData(callData) != CallTypeNone) { - if (holder->inherits(&JSArray::info)) { - builder.append("null"); - return StringifySucceeded; - } - return StringifyFailedDueToUndefinedValue; - } - - // Handle cycle detection, and put the holder on the stack. - if (!m_holderCycleDetector.add(object).second) { - throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures.")); - return StringifyFailed; - } - bool holderStackWasEmpty = m_holderStack.isEmpty(); - m_holderStack.append(object); - if (!holderStackWasEmpty) - return StringifySucceeded; - - // If this is the outermost call, then loop to handle everything on the holder stack. - TimeoutChecker localTimeoutChecker(m_exec->globalData().timeoutChecker); - localTimeoutChecker.reset(); - unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck(); - do { - while (m_holderStack.last().appendNextProperty(*this, builder)) { - if (m_exec->hadException()) - return StringifyFailed; - if (!--tickCount) { - if (localTimeoutChecker.didTimeOut(m_exec)) { - throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData())); - return StringifyFailed; - } - tickCount = localTimeoutChecker.ticksUntilNextCheck(); - } - } - m_holderCycleDetector.remove(m_holderStack.last().object()); - m_holderStack.removeLast(); - } while (!m_holderStack.isEmpty()); - return StringifySucceeded; -} - -inline bool Stringifier::willIndent() const -{ - return !m_gap.isEmpty(); -} - -inline void Stringifier::indent() -{ - // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent. - unsigned newSize = m_indent.length() + m_gap.length(); - if (newSize > m_repeatedGap.length()) - m_repeatedGap = makeUString(m_repeatedGap, m_gap); - ASSERT(newSize <= m_repeatedGap.length()); - m_indent = m_repeatedGap.substringSharingImpl(0, newSize); -} - -inline void Stringifier::unindent() -{ - ASSERT(m_indent.length() >= m_gap.length()); - m_indent = m_repeatedGap.substringSharingImpl(0, m_indent.length() - m_gap.length()); -} - -inline void Stringifier::startNewLine(UStringBuilder& builder) const -{ - if (m_gap.isEmpty()) - return; - builder.append('\n'); - builder.append(m_indent); -} - -inline Stringifier::Holder::Holder(JSObject* object) - : m_object(object) - , m_isArray(object->inherits(&JSArray::info)) - , m_index(0) -{ -} - -bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBuilder& builder) -{ - ASSERT(m_index <= m_size); - - ExecState* exec = stringifier.m_exec; - - // First time through, initialize. - if (!m_index) { - if (m_isArray) { - m_isJSArray = isJSArray(&exec->globalData(), m_object); - m_size = m_object->get(exec, exec->globalData().propertyNames->length).toUInt32(exec); - builder.append('['); - } else { - if (stringifier.m_usingArrayReplacer) - m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data(); - else { - PropertyNameArray objectPropertyNames(exec); - m_object->getOwnPropertyNames(exec, objectPropertyNames); - m_propertyNames = objectPropertyNames.releaseData(); - } - m_size = m_propertyNames->propertyNameVector().size(); - builder.append('{'); - } - stringifier.indent(); - } - - // Last time through, finish up and return false. - if (m_index == m_size) { - stringifier.unindent(); - if (m_size && builder[builder.length() - 1] != '{') - stringifier.startNewLine(builder); - builder.append(m_isArray ? ']' : '}'); - return false; - } - - // Handle a single element of the array or object. - unsigned index = m_index++; - unsigned rollBackPoint = 0; - StringifyResult stringifyResult; - if (m_isArray) { - // Get the value. - JSValue value; - if (m_isJSArray && asArray(m_object)->canGetIndex(index)) - value = asArray(m_object)->getIndex(index); - else { - PropertySlot slot(m_object); - if (!m_object->getOwnPropertySlot(exec, index, slot)) - slot.setUndefined(); - if (exec->hadException()) - return false; - value = slot.getValue(exec, index); - } - - // Append the separator string. - if (index) - builder.append(','); - stringifier.startNewLine(builder); - - // Append the stringified value. - stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, index); - } else { - // Get the value. - PropertySlot slot(m_object); - Identifier& propertyName = m_propertyNames->propertyNameVector()[index]; - if (!m_object->getOwnPropertySlot(exec, propertyName, slot)) - return true; - JSValue value = slot.getValue(exec, propertyName); - if (exec->hadException()) - return false; - - rollBackPoint = builder.length(); - - // Append the separator string. - if (builder[rollBackPoint - 1] != '{') - builder.append(','); - stringifier.startNewLine(builder); - - // Append the property name. - appendQuotedString(builder, propertyName.ustring()); - builder.append(':'); - if (stringifier.willIndent()) - builder.append(' '); - - // Append the stringified value. - stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, propertyName); - } - - // From this point on, no access to the this pointer or to any members, because the - // Holder object may have moved if the call to stringify pushed a new Holder onto - // m_holderStack. - - switch (stringifyResult) { - case StringifyFailed: - builder.append("null"); - break; - case StringifySucceeded: - break; - case StringifyFailedDueToUndefinedValue: - // This only occurs when get an undefined value for an object property. - // In this case we don't want the separator and property name that we - // already appended, so roll back. - builder.resize(rollBackPoint); - break; - } - - return true; -} - -// ------------------------------ JSONObject -------------------------------- - -const ClassInfo JSONObject::info = { "JSON", 0, 0, ExecState::jsonTable }; - -/* Source for JSONObject.lut.h -@begin jsonTable - parse JSONProtoFuncParse DontEnum|Function 1 - stringify JSONProtoFuncStringify DontEnum|Function 1 -@end -*/ - -// ECMA 15.8 - -bool JSONObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticFunctionSlot<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, slot); -} - -bool JSONObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticFunctionDescriptor<JSObject>(exec, ExecState::jsonTable(exec), this, propertyName, descriptor); -} - -void JSONObject::markStringifiers(MarkStack& markStack, Stringifier* stringifier) -{ - stringifier->markAggregate(markStack); -} - -class Walker { -public: - Walker(ExecState* exec, JSObject* function, CallType callType, CallData callData) - : m_exec(exec) - , m_function(function) - , m_callType(callType) - , m_callData(callData) - { - } - JSValue walk(JSValue unfiltered); -private: - JSValue callReviver(JSObject* thisObj, JSValue property, JSValue unfiltered) - { - JSValue args[] = { property, unfiltered }; - ArgList argList(args, 2); - return call(m_exec, m_function, m_callType, m_callData, thisObj, argList); - } - - friend class Holder; - - ExecState* m_exec; - JSObject* m_function; - CallType m_callType; - CallData m_callData; -}; - -// We clamp recursion well beyond anything reasonable, but we also have a timeout check -// to guard against "infinite" execution by inserting arbitrarily large objects. -static const unsigned maximumFilterRecursion = 40000; -enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, - ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember }; -NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) -{ - Vector<PropertyNameArray, 16> propertyStack; - Vector<uint32_t, 16> indexStack; - Vector<JSObject*, 16> objectStack; - Vector<JSArray*, 16> arrayStack; - - Vector<WalkerState, 16> stateStack; - WalkerState state = StateUnknown; - JSValue inValue = unfiltered; - JSValue outValue = jsNull(); - - TimeoutChecker localTimeoutChecker(m_exec->globalData().timeoutChecker); - localTimeoutChecker.reset(); - unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck(); - while (1) { - switch (state) { - arrayStartState: - case ArrayStartState: { - ASSERT(inValue.isObject()); - ASSERT(isJSArray(&m_exec->globalData(), asObject(inValue)) || asObject(inValue)->inherits(&JSArray::info)); - if (objectStack.size() + arrayStack.size() > maximumFilterRecursion) - return throwError(m_exec, createStackOverflowError(m_exec)); - - JSArray* array = asArray(inValue); - arrayStack.append(array); - indexStack.append(0); - // fallthrough - } - arrayStartVisitMember: - case ArrayStartVisitMember: { - if (!--tickCount) { - if (localTimeoutChecker.didTimeOut(m_exec)) - return throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData())); - tickCount = localTimeoutChecker.ticksUntilNextCheck(); - } - - JSArray* array = arrayStack.last(); - uint32_t index = indexStack.last(); - if (index == array->length()) { - outValue = array; - arrayStack.removeLast(); - indexStack.removeLast(); - break; - } - if (isJSArray(&m_exec->globalData(), array) && array->canGetIndex(index)) - inValue = array->getIndex(index); - else { - PropertySlot slot; - if (array->getOwnPropertySlot(m_exec, index, slot)) - inValue = slot.getValue(m_exec, index); - else - inValue = jsUndefined(); - } - - if (inValue.isObject()) { - stateStack.append(ArrayEndVisitMember); - goto stateUnknown; - } else - outValue = inValue; - // fallthrough - } - case ArrayEndVisitMember: { - JSArray* array = arrayStack.last(); - JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue); - if (filteredValue.isUndefined()) - array->deleteProperty(m_exec, indexStack.last()); - else { - if (isJSArray(&m_exec->globalData(), array) && array->canSetIndex(indexStack.last())) - array->setIndex(indexStack.last(), filteredValue); - else - array->put(m_exec, indexStack.last(), filteredValue); - } - if (m_exec->hadException()) - return jsNull(); - indexStack.last()++; - goto arrayStartVisitMember; - } - objectStartState: - case ObjectStartState: { - ASSERT(inValue.isObject()); - ASSERT(!isJSArray(&m_exec->globalData(), asObject(inValue)) && !asObject(inValue)->inherits(&JSArray::info)); - if (objectStack.size() + arrayStack.size() > maximumFilterRecursion) - return throwError(m_exec, createStackOverflowError(m_exec)); - - JSObject* object = asObject(inValue); - objectStack.append(object); - indexStack.append(0); - propertyStack.append(PropertyNameArray(m_exec)); - object->getOwnPropertyNames(m_exec, propertyStack.last()); - // fallthrough - } - objectStartVisitMember: - case ObjectStartVisitMember: { - if (!--tickCount) { - if (localTimeoutChecker.didTimeOut(m_exec)) - return throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData())); - tickCount = localTimeoutChecker.ticksUntilNextCheck(); - } - - JSObject* object = objectStack.last(); - uint32_t index = indexStack.last(); - PropertyNameArray& properties = propertyStack.last(); - if (index == properties.size()) { - outValue = object; - objectStack.removeLast(); - indexStack.removeLast(); - propertyStack.removeLast(); - break; - } - PropertySlot slot; - if (object->getOwnPropertySlot(m_exec, properties[index], slot)) - inValue = slot.getValue(m_exec, properties[index]); - else - inValue = jsUndefined(); - - // The holder may be modified by the reviver function so any lookup may throw - if (m_exec->hadException()) - return jsNull(); - - if (inValue.isObject()) { - stateStack.append(ObjectEndVisitMember); - goto stateUnknown; - } else - outValue = inValue; - // fallthrough - } - case ObjectEndVisitMember: { - JSObject* object = objectStack.last(); - Identifier prop = propertyStack.last()[indexStack.last()]; - PutPropertySlot slot; - JSValue filteredValue = callReviver(object, jsString(m_exec, prop.ustring()), outValue); - if (filteredValue.isUndefined()) - object->deleteProperty(m_exec, prop); - else - object->put(m_exec, prop, filteredValue, slot); - if (m_exec->hadException()) - return jsNull(); - indexStack.last()++; - goto objectStartVisitMember; - } - stateUnknown: - case StateUnknown: - if (!inValue.isObject()) { - outValue = inValue; - break; - } - JSObject* object = asObject(inValue); - if (isJSArray(&m_exec->globalData(), object) || object->inherits(&JSArray::info)) - goto arrayStartState; - goto objectStartState; - } - if (stateStack.isEmpty()) - break; - - state = stateStack.last(); - stateStack.removeLast(); - - if (!--tickCount) { - if (localTimeoutChecker.didTimeOut(m_exec)) - return throwError(m_exec, createInterruptedExecutionException(&m_exec->globalData())); - tickCount = localTimeoutChecker.ticksUntilNextCheck(); - } - } - JSObject* finalHolder = constructEmptyObject(m_exec); - PutPropertySlot slot; - finalHolder->put(m_exec, m_exec->globalData().propertyNames->emptyIdentifier, outValue, slot); - return callReviver(finalHolder, jsEmptyString(m_exec), outValue); -} - -// ECMA-262 v5 15.12.2 -EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec) -{ - if (!exec->argumentCount()) - return throwVMError(exec, createError(exec, "JSON.parse requires at least one parameter")); - JSValue value = exec->argument(0); - UString source = value.toString(exec); - if (exec->hadException()) - return JSValue::encode(jsNull()); - - LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON); - JSValue unfiltered = jsonParser.tryLiteralParse(); - if (!unfiltered) - return throwVMError(exec, createSyntaxError(exec, "Unable to parse JSON string")); - - if (exec->argumentCount() < 2) - return JSValue::encode(unfiltered); - - JSValue function = exec->argument(1); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return JSValue::encode(unfiltered); - return JSValue::encode(Walker(exec, asObject(function), callType, callData).walk(unfiltered)); -} - -// ECMA-262 v5 15.12.3 -EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec) -{ - if (!exec->argumentCount()) - return throwVMError(exec, createError(exec, "No input to stringify")); - JSValue value = exec->argument(0); - JSValue replacer = exec->argument(1); - JSValue space = exec->argument(2); - return JSValue::encode(Stringifier(exec, replacer, space).stringify(value)); -} - -UString JSONStringify(ExecState* exec, JSValue value, unsigned indent) -{ - JSValue result = Stringifier(exec, jsNull(), jsNumber(indent)).stringify(value); - if (result.isUndefinedOrNull()) - return UString(); - return result.getString(exec); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSONObject.h b/JavaScriptCore/runtime/JSONObject.h deleted file mode 100644 index f64be12..0000000 --- a/JavaScriptCore/runtime/JSONObject.h +++ /dev/null @@ -1,61 +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 JSONObject_h -#define JSONObject_h - -#include "JSObjectWithGlobalObject.h" - -namespace JSC { - - class Stringifier; - - class JSONObject : public JSObjectWithGlobalObject { - public: - JSONObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure); - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - static void markStringifiers(MarkStack&, Stringifier*); - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; - - private: - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - }; - - UString JSONStringify(ExecState* exec, JSValue value, unsigned indent); - -} // namespace JSC - -#endif // JSONObject_h diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp deleted file mode 100644 index 30e40e4..0000000 --- a/JavaScriptCore/runtime/JSObject.cpp +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Eric Seidel (eric@webkit.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSObject.h" - -#include "DatePrototype.h" -#include "ErrorConstructor.h" -#include "GetterSetter.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "NativeErrorConstructor.h" -#include "ObjectPrototype.h" -#include "PropertyDescriptor.h" -#include "PropertyNameArray.h" -#include "Lookup.h" -#include "Nodes.h" -#include "Operations.h" -#include <math.h> -#include <wtf/Assertions.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSObject); - -const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property."; - -static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - // 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) || (mode == IncludeDontEnumProperties))) - propertyNames.add(entry->key()); - } - } -} - -void JSObject::markChildren(MarkStack& markStack) -{ -#ifndef NDEBUG - bool wasCheckingForDefaultMarkViolation = markStack.m_isCheckingForDefaultMarkViolation; - markStack.m_isCheckingForDefaultMarkViolation = false; -#endif - - markChildrenDirect(markStack); - -#ifndef NDEBUG - markStack.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation; -#endif -} - -UString JSObject::className() const -{ - const ClassInfo* info = classInfo(); - if (info) - return info->className; - return "Object"; -} - -bool JSObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) -{ - return getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); -} - -static void throwSetterError(ExecState* exec) -{ - throwError(exec, createTypeError(exec, "setting a property that has only a getter")); -} - -// ECMA 8.6.2.2 -void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - ASSERT(value); - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - if (propertyName == exec->propertyNames().underscoreProto) { - // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla. - if (!value.isObject() && !value.isNull()) - return; - if (!setPrototypeWithCycleCheck(value)) - throwError(exec, createError(exec, "cyclic __proto__ value")); - return; - } - - // Check if there are any setters or getters in the prototype chain - JSValue prototype; - for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) { - prototype = obj->prototype(); - if (prototype.isNull()) { - if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode()) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); - return; - } - } - - unsigned attributes; - JSCell* specificValue; - if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) { - if (slot.isStrictMode()) - throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); - return; - } - - for (JSObject* obj = this; ; obj = asObject(prototype)) { - if (JSValue gs = obj->getDirect(propertyName)) { - if (gs.isGetterSetter()) { - JSObject* setterFunc = asGetterSetter(gs)->setter(); - if (!setterFunc) { - throwSetterError(exec); - return; - } - - CallData callData; - CallType callType = setterFunc->getCallData(callData); - MarkedArgumentBuffer args; - args.append(value); - call(exec, setterFunc, callType, callData, this, args); - return; - } - - // If there's an existing property on the object or one of its - // prototypes it should be replaced, so break here. - break; - } - - prototype = obj->prototype(); - if (prototype.isNull()) - break; - } - - if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode()) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); - return; -} - -void JSObject::put(ExecState* exec, unsigned propertyName, JSValue value) -{ - PutPropertySlot slot; - put(exec, Identifier::from(exec, propertyName), value, slot); -} - -void JSObject::putWithAttributes(JSGlobalData* globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) -{ - putDirectInternal(*globalData, propertyName, value, attributes, checkReadOnly, slot); -} - -void JSObject::putWithAttributes(JSGlobalData* globalData, const Identifier& propertyName, JSValue value, unsigned attributes) -{ - putDirectInternal(*globalData, propertyName, value, attributes); -} - -void JSObject::putWithAttributes(JSGlobalData* globalData, unsigned propertyName, JSValue value, unsigned attributes) -{ - putWithAttributes(globalData, Identifier::from(globalData, propertyName), value, attributes); -} - -void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) -{ - putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot); -} - -void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) -{ - putDirectInternal(exec->globalData(), propertyName, value, attributes); -} - -void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes) -{ - putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes); -} - -bool JSObject::hasProperty(ExecState* exec, const Identifier& propertyName) const -{ - PropertySlot slot; - return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot); -} - -bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const -{ - PropertySlot slot; - return const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot); -} - -// ECMA 8.6.2.5 -bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - unsigned attributes; - JSCell* specificValue; - if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) { - if ((attributes & DontDelete)) - return false; - removeDirect(propertyName); - return true; - } - - // Look in the static hashtable of properties - const HashEntry* entry = findPropertyHashEntry(exec, propertyName); - if (entry && entry->attributes() & DontDelete) - return false; // this builtin property can't be deleted - - // FIXME: Should the code here actually do some deletion? - return true; -} - -bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) const -{ - PropertySlot slot; - return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot); -} - -bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName) -{ - return deleteProperty(exec, Identifier::from(exec, propertyName)); -} - -static ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName) -{ - JSValue function = object->get(exec, propertyName); - CallData callData; - CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) - return exec->exception(); - - // Prevent "toString" and "valueOf" from observing execution if an exception - // is pending. - if (exec->hadException()) - return exec->exception(); - - JSValue result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList()); - ASSERT(!result.isGetterSetter()); - if (exec->hadException()) - return exec->exception(); - if (result.isObject()) - return JSValue(); - return result; -} - -bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) -{ - result = defaultValue(exec, PreferNumber); - number = result.toNumber(exec); - return !result.isString(); -} - -// ECMA 8.6.2.6 -JSValue JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const -{ - // Must call toString first for Date objects. - if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) { - JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().toString); - if (value) - return value; - value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf); - if (value) - return value; - } else { - JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf); - if (value) - return value; - value = callDefaultValueFunction(exec, this, exec->propertyNames().toString); - if (value) - return value; - } - - ASSERT(!exec->hadException()); - - return throwError(exec, createTypeError(exec, "No default value")); -} - -const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifier& propertyName) const -{ - for (const ClassInfo* info = classInfo(); info; info = info->parentClass) { - if (const HashTable* propHashTable = info->propHashTable(exec)) { - if (const HashEntry* entry = propHashTable->entry(exec, propertyName)) - return entry; - } - } - return 0; -} - -void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes) -{ - JSValue object = getDirect(propertyName); - if (object && object.isGetterSetter()) { - ASSERT(m_structure->hasGetterSetterProperties()); - asGetterSetter(object)->setGetter(getterFunction); - return; - } - - PutPropertySlot slot; - GetterSetter* getterSetter = new (exec) GetterSetter(exec); - putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Getter, true, slot); - - // putDirect will change our Structure if we add a new property. For - // getters and setters, though, we also need to change our Structure - // if we override an existing non-getter or non-setter. - if (slot.type() != PutPropertySlot::NewProperty) { - if (!m_structure->isDictionary()) { - RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure); - setStructure(structure.release()); - } - } - - m_structure->setHasGetterSetterProperties(true); - getterSetter->setGetter(getterFunction); -} - -void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes) -{ - JSValue object = getDirect(propertyName); - if (object && object.isGetterSetter()) { - ASSERT(m_structure->hasGetterSetterProperties()); - asGetterSetter(object)->setSetter(setterFunction); - return; - } - - PutPropertySlot slot; - GetterSetter* getterSetter = new (exec) GetterSetter(exec); - putDirectInternal(exec->globalData(), propertyName, getterSetter, attributes | Setter, true, slot); - - // putDirect will change our Structure if we add a new property. For - // getters and setters, though, we also need to change our Structure - // if we override an existing non-getter or non-setter. - if (slot.type() != PutPropertySlot::NewProperty) { - if (!m_structure->isDictionary()) { - RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure); - setStructure(structure.release()); - } - } - - m_structure->setHasGetterSetterProperties(true); - getterSetter->setSetter(setterFunction); -} - -JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName) -{ - JSObject* object = this; - while (true) { - if (JSValue value = object->getDirect(propertyName)) { - if (!value.isGetterSetter()) - return jsUndefined(); - JSObject* functionObject = asGetterSetter(value)->getter(); - if (!functionObject) - return jsUndefined(); - return functionObject; - } - - if (!object->prototype() || !object->prototype().isObject()) - return jsUndefined(); - object = asObject(object->prototype()); - } -} - -JSValue JSObject::lookupSetter(ExecState*, const Identifier& propertyName) -{ - JSObject* object = this; - while (true) { - if (JSValue value = object->getDirect(propertyName)) { - if (!value.isGetterSetter()) - return jsUndefined(); - JSObject* functionObject = asGetterSetter(value)->setter(); - if (!functionObject) - return jsUndefined(); - return functionObject; - } - - if (!object->prototype() || !object->prototype().isObject()) - return jsUndefined(); - object = asObject(object->prototype()); - } -} - -bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto) -{ - if (!value.isObject()) - return false; - - if (!proto.isObject()) { - throwError(exec, createTypeError(exec, "instanceof called on an object with an invalid prototype property.")); - return false; - } - - JSObject* object = asObject(value); - while ((object = object->prototype().getObject())) { - if (proto == object) - return true; - } - return false; -} - -bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyName) const -{ - PropertyDescriptor descriptor; - if (!const_cast<JSObject*>(this)->getOwnPropertyDescriptor(exec, propertyName, descriptor)) - return false; - return descriptor.enumerable(); -} - -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, EnumerationMode mode) -{ - getOwnPropertyNames(exec, propertyNames, mode); - - if (prototype().isNull()) - return; - - JSObject* prototype = asObject(this->prototype()); - while(1) { - if (prototype->structure()->typeInfo().overridesGetPropertyNames()) { - prototype->getPropertyNames(exec, propertyNames, mode); - break; - } - prototype->getOwnPropertyNames(exec, propertyNames, mode); - JSValue nextProto = prototype->prototype(); - if (nextProto.isNull()) - break; - prototype = asObject(nextProto); - } -} - -void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - m_structure->getPropertyNames(propertyNames, mode); - getClassPropertyNames(exec, classInfo(), propertyNames, mode); -} - -bool JSObject::toBoolean(ExecState*) const -{ - return true; -} - -double JSObject::toNumber(ExecState* exec) const -{ - JSValue primitive = toPrimitive(exec, PreferNumber); - if (exec->hadException()) // should be picked up soon in Nodes.cpp - return 0.0; - return primitive.toNumber(exec); -} - -UString JSObject::toString(ExecState* exec) const -{ - JSValue primitive = toPrimitive(exec, PreferString); - if (exec->hadException()) - return ""; - return primitive.toString(exec); -} - -JSObject* JSObject::toObject(ExecState*) const -{ - return const_cast<JSObject*>(this); -} - -JSObject* JSObject::toThisObject(ExecState*) const -{ - return const_cast<JSObject*>(this); -} - -JSValue JSObject::toStrictThisObject(ExecState*) const -{ - return const_cast<JSObject*>(this); -} - -JSObject* JSObject::unwrappedObject() -{ - return this; -} - -void JSObject::removeDirect(const Identifier& propertyName) -{ - size_t offset; - if (m_structure->isUncacheableDictionary()) { - offset = m_structure->removePropertyWithoutTransition(propertyName); - if (offset != WTF::notFound) - putDirectOffset(offset, jsUndefined()); - return; - } - - RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset); - setStructure(structure.release()); - if (offset != WTF::notFound) - putDirectOffset(offset, jsUndefined()); -} - -void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr) -{ - putDirectFunction(Identifier(exec, function->name(exec)), function, attr); -} - -void JSObject::putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr) -{ - putDirectFunction(Identifier(exec, function->name(exec)), function, attr); -} - -void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr) -{ - putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr); -} - -void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr) -{ - putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr); -} - -NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location) -{ - if (JSObject* getterFunction = asGetterSetter(*location)->getter()) { - if (!structure()->isDictionary()) - slot.setCacheableGetterSlot(this, getterFunction, offsetForLocation(location)); - else - slot.setGetterSlot(getterFunction); - } else - slot.setUndefined(); -} - -Structure* JSObject::createInheritorID() -{ - m_inheritorID = JSObject::createStructure(this); - return m_inheritorID.get(); -} - -void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize) -{ - allocatePropertyStorageInline(oldSize, newSize); -} - -bool JSObject::getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - unsigned attributes = 0; - JSCell* cell = 0; - size_t offset = m_structure->get(propertyName, attributes, cell); - if (offset == WTF::notFound) - return false; - descriptor.setDescriptor(getDirectOffset(offset), attributes); - return true; -} - -bool JSObject::getPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - JSObject* object = this; - while (true) { - if (object->getOwnPropertyDescriptor(exec, propertyName, descriptor)) - return true; - JSValue prototype = object->prototype(); - if (!prototype.isObject()) - return false; - object = asObject(prototype); - } -} - -static bool putDescriptor(ExecState* exec, JSObject* target, const Identifier& propertyName, PropertyDescriptor& descriptor, unsigned attributes, JSValue oldValue) -{ - if (descriptor.isGenericDescriptor() || descriptor.isDataDescriptor()) { - target->putWithAttributes(exec, propertyName, descriptor.value() ? descriptor.value() : oldValue, attributes & ~(Getter | Setter)); - return true; - } - attributes &= ~ReadOnly; - if (descriptor.getter() && descriptor.getter().isObject()) - target->defineGetter(exec, propertyName, asObject(descriptor.getter()), attributes); - if (exec->hadException()) - return false; - if (descriptor.setter() && descriptor.setter().isObject()) - target->defineSetter(exec, propertyName, asObject(descriptor.setter()), attributes); - return !exec->hadException(); -} - -bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException) -{ - // If we have a new property we can just put it on normally - PropertyDescriptor current; - if (!getOwnPropertyDescriptor(exec, propertyName, current)) - return putDescriptor(exec, this, propertyName, descriptor, descriptor.attributes(), jsUndefined()); - - if (descriptor.isEmpty()) - return true; - - if (current.equalTo(exec, descriptor)) - return true; - - // Filter out invalid changes - if (!current.configurable()) { - if (descriptor.configurable()) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property.")); - return false; - } - if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property.")); - return false; - } - } - - // A generic descriptor is simply changing the attributes of an existing property - if (descriptor.isGenericDescriptor()) { - if (!current.attributesEqual(descriptor)) { - deleteProperty(exec, propertyName); - putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); - } - return true; - } - - // Changing between a normal property or an accessor property - if (descriptor.isDataDescriptor() != current.isDataDescriptor()) { - if (!current.configurable()) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property.")); - return false; - } - deleteProperty(exec, propertyName); - return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value() ? current.value() : jsUndefined()); - } - - // Changing the value and attributes of an existing property - if (descriptor.isDataDescriptor()) { - if (!current.configurable()) { - if (!current.writable() && descriptor.writable()) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property.")); - return false; - } - if (!current.writable()) { - if (descriptor.value() || !JSValue::strictEqual(exec, current.value(), descriptor.value())) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property.")); - return false; - } - } - } else if (current.attributesEqual(descriptor)) { - if (!descriptor.value()) - return true; - PutPropertySlot slot; - put(exec, propertyName, descriptor.value(), slot); - if (exec->hadException()) - return false; - return true; - } - deleteProperty(exec, propertyName); - return putDescriptor(exec, this, propertyName, descriptor, current.attributesWithOverride(descriptor), current.value()); - } - - // Changing the accessor functions of an existing accessor property - ASSERT(descriptor.isAccessorDescriptor()); - if (!current.configurable()) { - if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change the setter of an unconfigurable property.")); - return false; - } - if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) { - if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change the getter of an unconfigurable property.")); - return false; - } - } - JSValue accessor = getDirect(propertyName); - if (!accessor) - return false; - GetterSetter* getterSetter = asGetterSetter(accessor); - if (current.attributesEqual(descriptor)) { - if (descriptor.setter()) - getterSetter->setSetter(asObject(descriptor.setter())); - if (descriptor.getter()) - getterSetter->setGetter(asObject(descriptor.getter())); - return true; - } - deleteProperty(exec, propertyName); - unsigned attrs = current.attributesWithOverride(descriptor); - if (descriptor.setter()) - attrs |= Setter; - if (descriptor.getter()) - attrs |= Getter; - putDirect(propertyName, getterSetter, attrs); - return true; -} - -JSObject* throwTypeError(ExecState* exec, const UString& message) -{ - return throwError(exec, createTypeError(exec, message)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h deleted file mode 100644 index 803abfd..0000000 --- a/JavaScriptCore/runtime/JSObject.h +++ /dev/null @@ -1,771 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSObject_h -#define JSObject_h - -#include "ArgList.h" -#include "ClassInfo.h" -#include "CommonIdentifiers.h" -#include "Completion.h" -#include "CallFrame.h" -#include "JSCell.h" -#include "JSNumberCell.h" -#include "MarkStack.h" -#include "PropertySlot.h" -#include "PutPropertySlot.h" -#include "ScopeChain.h" -#include "Structure.h" -#include "JSGlobalData.h" -#include "JSString.h" -#include <wtf/StdLibExtras.h> - -namespace JSC { - - inline JSCell* getJSFunction(JSGlobalData& globalData, JSValue value) - { - if (value.isCell() && (value.asCell()->vptr() == globalData.jsFunctionVPtr)) - return value.asCell(); - return 0; - } - - class HashEntry; - class InternalFunction; - class PropertyDescriptor; - class PropertyNameArray; - class Structure; - struct HashTable; - - JSObject* throwTypeError(ExecState*, const UString&); - extern const char* StrictModeReadonlyPropertyWriteError; - - // ECMA 262-3 8.6.1 - // Property attributes - enum Attribute { - None = 0, - ReadOnly = 1 << 1, // property can be only read, not written - DontEnum = 1 << 2, // property doesn't appear in (for .. in ..) - DontDelete = 1 << 3, // property can't be deleted - Function = 1 << 4, // property is a function - only used by static hashtables - Getter = 1 << 5, // property is a getter - Setter = 1 << 6 // property is a setter - }; - - typedef EncodedJSValue* PropertyStorage; - typedef const EncodedJSValue* ConstPropertyStorage; - - class JSObject : public JSCell { - friend class BatchedTransitionOptimizer; - friend class JIT; - friend class JSCell; - friend void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot); - - public: - explicit JSObject(NonNullPassRefPtr<Structure>); - - virtual void markChildren(MarkStack&); - ALWAYS_INLINE void markChildrenDirect(MarkStack& markStack); - - // The inline virtual destructor cannot be the first virtual function declared - // in the class as it results in the vtable being generated as a weak symbol - virtual ~JSObject(); - - JSValue prototype() const; - void setPrototype(JSValue prototype); - bool setPrototypeWithCycleCheck(JSValue prototype); - - void setStructure(NonNullPassRefPtr<Structure>); - Structure* inheritorID(); - - virtual UString className() const; - - JSValue get(ExecState*, const Identifier& propertyName) const; - JSValue get(ExecState*, unsigned propertyName) const; - - bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - bool getPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual void put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&); - virtual void put(ExecState*, unsigned propertyName, JSValue value); - - virtual void putWithAttributes(JSGlobalData*, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot); - virtual void putWithAttributes(JSGlobalData*, const Identifier& propertyName, JSValue value, unsigned attributes); - virtual void putWithAttributes(JSGlobalData*, unsigned propertyName, JSValue 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; - - bool hasProperty(ExecState*, const Identifier& propertyName) const; - bool hasProperty(ExecState*, unsigned propertyName) const; - bool hasOwnProperty(ExecState*, const Identifier& propertyName) const; - - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual bool deleteProperty(ExecState*, unsigned propertyName); - - virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const; - - virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty); - - virtual void getPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value); - virtual bool toBoolean(ExecState*) const; - virtual double toNumber(ExecState*) const; - virtual UString toString(ExecState*) const; - virtual JSObject* toObject(ExecState*) const; - - virtual JSObject* toThisObject(ExecState*) const; - virtual JSValue toStrictThisObject(ExecState*) const; - virtual JSObject* unwrappedObject(); - - bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const; - - // This get function only looks at the property map. - JSValue getDirect(const Identifier& propertyName) const - { - size_t offset = m_structure->get(propertyName); - return offset != WTF::notFound ? getDirectOffset(offset) : JSValue(); - } - - JSValue* getDirectLocation(const Identifier& propertyName) - { - size_t offset = m_structure->get(propertyName); - return offset != WTF::notFound ? locationForOffset(offset) : 0; - } - - JSValue* getDirectLocation(const Identifier& propertyName, unsigned& attributes) - { - JSCell* specificFunction; - size_t offset = m_structure->get(propertyName, attributes, specificFunction); - return offset != WTF::notFound ? locationForOffset(offset) : 0; - } - - size_t offsetForLocation(JSValue* location) const - { - return location - reinterpret_cast<const JSValue*>(propertyStorage()); - } - - void transitionTo(Structure*); - - void removeDirect(const Identifier& propertyName); - bool hasCustomProperties() { return !m_structure->isEmpty(); } - bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); } - - bool putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); - void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0); - bool putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&); - - 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 putDirectFunction(ExecState* exec, JSFunction* function, unsigned attr = 0); - - void putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attr = 0); - void putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attr = 0); - void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0); - void putDirectFunctionWithoutTransition(ExecState* exec, JSFunction* function, unsigned attr = 0); - - // Fast access to known property offsets. - JSValue getDirectOffset(size_t offset) const { return JSValue::decode(propertyStorage()[offset]); } - void putDirectOffset(size_t offset, JSValue value) { propertyStorage()[offset] = JSValue::encode(value); } - - void fillGetterPropertySlot(PropertySlot&, JSValue* location); - - virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes = 0); - virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes = 0); - virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName); - virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName); - virtual bool defineOwnProperty(ExecState*, const Identifier& propertyName, PropertyDescriptor&, bool shouldThrow); - - virtual bool isGlobalObject() const { return false; } - virtual bool isVariableObject() const { return false; } - virtual bool isActivationObject() const { return false; } - virtual bool isStrictModeFunction() const { return false; } - virtual bool isErrorInstance() const { return false; } - - virtual ComplType exceptionType() const { return Throw; } - - void allocatePropertyStorage(size_t oldSize, size_t newSize); - void allocatePropertyStorageInline(size_t oldSize, size_t newSize); - bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); } - - static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3; - static const unsigned nonInlineBaseStorageCapacity = 16; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - void flattenDictionaryObject() - { - m_structure->flattenDictionaryStructure(this); - } - - void putAnonymousValue(unsigned index, JSValue value) - { - ASSERT(index < m_structure->anonymousSlotCount()); - *locationForOffset(index) = value; - } - JSValue getAnonymousValue(unsigned index) const - { - ASSERT(index < m_structure->anonymousSlotCount()); - return *locationForOffset(index); - } - - protected: - static const unsigned StructureFlags = 0; - - private: - // Nobody should ever ask any of these questions on something already known to be a JSObject. - using JSCell::isAPIValueWrapper; - using JSCell::isGetterSetter; - using JSCell::toObject; - void getObject(); - void getString(ExecState* exec); - void isObject(); - void isString(); - - 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]); - } - - bool putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*); - bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot); - void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0); - - bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - - const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const; - Structure* createInheritorID(); - - union { - PropertyStorage m_externalStorage; - EncodedJSValue m_inlineStorage[inlineStorageCapacity]; - }; - - RefPtr<Structure> m_inheritorID; - }; - -inline JSObject* asObject(JSCell* cell) -{ - ASSERT(cell->isObject()); - return static_cast<JSObject*>(cell); -} - -inline JSObject* asObject(JSValue value) -{ - return asObject(value.asCell()); -} - -inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure) - : JSCell(structure.releaseRef()) // ~JSObject balances this ref() -{ - ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity); - ASSERT(m_structure->isEmpty()); - ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype())); - ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0); -} - -inline JSObject::~JSObject() -{ - ASSERT(m_structure); - if (!isUsingInlineStorage()) - delete [] m_externalStorage; - m_structure->deref(); -} - -inline JSValue JSObject::prototype() const -{ - return m_structure->storedPrototype(); -} - -inline bool JSObject::setPrototypeWithCycleCheck(JSValue prototype) -{ - JSValue nextPrototypeValue = prototype; - while (nextPrototypeValue && nextPrototypeValue.isObject()) { - JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject(); - if (nextPrototype == this) - return false; - nextPrototypeValue = nextPrototype->prototype(); - } - setPrototype(prototype); - return true; -} - -inline void JSObject::setPrototype(JSValue prototype) -{ - ASSERT(prototype); - RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype); - setStructure(newStructure.release()); -} - -inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure) -{ - m_structure->deref(); - m_structure = structure.leakRef(); // ~JSObject balances this ref() -} - -inline Structure* JSObject::inheritorID() -{ - if (m_inheritorID) - return m_inheritorID.get(); - return createInheritorID(); -} - -inline bool Structure::isUsingInlineStorage() const -{ - return (propertyStorageCapacity() == JSObject::inlineStorageCapacity); -} - -inline bool JSCell::inherits(const ClassInfo* info) const -{ - for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) { - if (ci == info) - return true; - } - return false; -} - -// this method is here to be after the inline declaration of JSCell::inherits -inline bool JSValue::inherits(const ClassInfo* classInfo) const -{ - return isCell() && asCell()->inherits(classInfo); -} - -ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (JSValue* location = getDirectLocation(propertyName)) { - if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter()) - fillGetterPropertySlot(slot, location); - else - slot.setValueSlot(this, location, offsetForLocation(location)); - return true; - } - - // non-standard Netscape extension - if (propertyName == exec->propertyNames().underscoreProto) { - slot.setValue(prototype()); - return true; - } - - return false; -} - -// It may seem crazy to inline a function this large, especially a virtual function, -// but it makes a big difference to property lookup that derived classes can inline their -// base class call to this. -ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return inlineGetOwnPropertySlot(exec, propertyName, slot); -} - -ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (!structure()->typeInfo().overridesGetOwnPropertySlot()) - return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot); - return getOwnPropertySlot(exec, propertyName, slot); -} - -// It may seem crazy to inline a function this large but it makes a big difference -// since this is function very hot in variable lookup -ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - JSObject* object = this; - while (true) { - if (object->fastGetOwnPropertySlot(exec, propertyName, slot)) - return true; - JSValue prototype = object->prototype(); - if (!prototype.isObject()) - return false; - object = asObject(prototype); - } -} - -ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) -{ - JSObject* object = this; - while (true) { - if (object->getOwnPropertySlot(exec, propertyName, slot)) - return true; - JSValue prototype = object->prototype(); - if (!prototype.isObject()) - return false; - object = asObject(prototype); - } -} - -inline JSValue JSObject::get(ExecState* exec, const Identifier& propertyName) const -{ - PropertySlot slot(this); - if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot)) - return slot.getValue(exec, propertyName); - - return jsUndefined(); -} - -inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const -{ - PropertySlot slot(this); - if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot)) - return slot.getValue(exec, propertyName); - - return jsUndefined(); -} - -inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction) -{ - ASSERT(value); - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - if (m_structure->isDictionary()) { - unsigned currentAttributes; - JSCell* currentSpecificFunction; - size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction); - if (offset != WTF::notFound) { - // If there is currently a specific function, and there now either isn't, - // or the new value is different, then despecify. - if (currentSpecificFunction && (specificFunction != currentSpecificFunction)) - m_structure->despecifyDictionaryFunction(propertyName); - if (checkReadOnly && currentAttributes & ReadOnly) - return false; - - putDirectOffset(offset, value); - // At this point, the objects structure only has a specific value set if previously there - // had been one set, and if the new value being specified is the same (otherwise we would - // have despecified, above). So, if currentSpecificFunction is not set, or if the new - // value is different (or there is no new value), then the slot now has no value - and - // as such it is cachable. - // If there was previously a value, and the new value is the same, then we cannot cache. - if (!currentSpecificFunction || (specificFunction != currentSpecificFunction)) - slot.setExistingProperty(this, offset); - return true; - } - - size_t currentCapacity = m_structure->propertyStorageCapacity(); - offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction); - if (currentCapacity != m_structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity()); - - ASSERT(offset < m_structure->propertyStorageCapacity()); - putDirectOffset(offset, value); - // See comment on setNewProperty call below. - if (!specificFunction) - slot.setNewProperty(this, offset); - return true; - } - - size_t offset; - size_t currentCapacity = m_structure->propertyStorageCapacity(); - if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) { - if (currentCapacity != structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); - - ASSERT(offset < structure->propertyStorageCapacity()); - setStructure(structure.release()); - putDirectOffset(offset, value); - // This is a new property; transitions with specific values are not currently cachable, - // so leave the slot in an uncachable state. - if (!specificFunction) - slot.setNewProperty(this, offset); - return true; - } - - unsigned currentAttributes; - JSCell* currentSpecificFunction; - offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction); - if (offset != WTF::notFound) { - if (checkReadOnly && currentAttributes & ReadOnly) - return false; - - // There are three possibilities here: - // (1) There is an existing specific value set, and we're overwriting with *the same value*. - // * Do nothing - no need to despecify, but that means we can't cache (a cached - // put could write a different value). Leave the slot in an uncachable state. - // (2) There is a specific value currently set, but we're writing a different value. - // * First, we have to despecify. Having done so, this is now a regular slot - // with no specific value, so go ahead & cache like normal. - // (3) Normal case, there is no specific value set. - // * Go ahead & cache like normal. - if (currentSpecificFunction) { - // case (1) Do the put, then return leaving the slot uncachable. - if (specificFunction == currentSpecificFunction) { - putDirectOffset(offset, value); - return true; - } - // case (2) Despecify, fall through to (3). - setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName)); - } - - // case (3) set the slot, do the put, return. - slot.setExistingProperty(this, offset); - putDirectOffset(offset, value); - return true; - } - - // If we have a specific function, we may have got to this point if there is - // already a transition with the correct property name and attributes, but - // specialized to a different function. In this case we just want to give up - // and despecialize the transition. - // In this case we clear the value of specificFunction which will result - // in us adding a non-specific transition, and any subsequent lookup in - // Structure::addPropertyTransitionToExistingStructure will just use that. - if (specificFunction && m_structure->hasTransition(propertyName, attributes)) - specificFunction = 0; - - RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset); - - if (currentCapacity != structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); - - ASSERT(offset < structure->propertyStorageCapacity()); - setStructure(structure.release()); - putDirectOffset(offset, value); - // This is a new property; transitions with specific values are not currently cachable, - // so leave the slot in an uncachable state. - if (!specificFunction) - slot.setNewProperty(this, offset); - return true; -} - -inline bool 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)); - - return 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 bool 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)); - - return 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 bool JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - return putDirectInternal(propertyName, value, 0, false, slot, 0); -} - -inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) -{ - putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, value); -} - -inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr) -{ - PutPropertySlot slot; - putDirectInternal(propertyName, value, attr, false, slot, value); -} - -inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attributes) -{ - size_t currentCapacity = m_structure->propertyStorageCapacity(); - size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, 0); - if (currentCapacity != m_structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity()); - putDirectOffset(offset, value); -} - -inline void JSObject::putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attributes) -{ - size_t currentCapacity = m_structure->propertyStorageCapacity(); - size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value); - if (currentCapacity != m_structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity()); - putDirectOffset(offset, value); -} - -inline void JSObject::transitionTo(Structure* newStructure) -{ - if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity()) - allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity()); - setStructure(newStructure); -} - -inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const -{ - return defaultValue(exec, preferredType); -} - -inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName) const -{ - PropertySlot slot(asValue()); - return get(exec, propertyName, slot); -} - -inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const -{ - if (UNLIKELY(!isCell())) { - JSObject* prototype = synthesizePrototype(exec); - if (propertyName == exec->propertyNames().underscoreProto) - return prototype; - if (!prototype->getPropertySlot(exec, propertyName, slot)) - return jsUndefined(); - return slot.getValue(exec, propertyName); - } - JSCell* cell = asCell(); - while (true) { - if (cell->fastGetOwnPropertySlot(exec, propertyName, slot)) - return slot.getValue(exec, propertyName); - JSValue prototype = asObject(cell)->prototype(); - if (!prototype.isObject()) - return jsUndefined(); - cell = asObject(prototype); - } -} - -inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const -{ - PropertySlot slot(asValue()); - return get(exec, propertyName, slot); -} - -inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const -{ - if (UNLIKELY(!isCell())) { - JSObject* prototype = synthesizePrototype(exec); - if (!prototype->getPropertySlot(exec, propertyName, slot)) - return jsUndefined(); - return slot.getValue(exec, propertyName); - } - JSCell* cell = const_cast<JSCell*>(asCell()); - while (true) { - if (cell->getOwnPropertySlot(exec, propertyName, slot)) - return slot.getValue(exec, propertyName); - JSValue prototype = asObject(cell)->prototype(); - if (!prototype.isObject()) - return jsUndefined(); - cell = prototype.asCell(); - } -} - -inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - if (UNLIKELY(!isCell())) { - synthesizeObject(exec)->put(exec, propertyName, value, slot); - return; - } - asCell()->put(exec, propertyName, value, slot); -} - -inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - ASSERT(isCell() && isObject()); - if (!asObject(asCell())->putDirect(propertyName, value, slot) && slot.isStrictMode()) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); -} - -inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value) -{ - if (UNLIKELY(!isCell())) { - synthesizeObject(exec)->put(exec, propertyName, value); - return; - } - asCell()->put(exec, propertyName, value); -} - -ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_t newSize) -{ - ASSERT(newSize > oldSize); - - // It's important that this function not rely on m_structure, since - // we might be in the middle of a transition. - bool wasInline = (oldSize == JSObject::inlineStorageCapacity); - - PropertyStorage oldPropertyStorage = (wasInline ? m_inlineStorage : m_externalStorage); - PropertyStorage newPropertyStorage = new EncodedJSValue[newSize]; - - for (unsigned i = 0; i < oldSize; ++i) - newPropertyStorage[i] = oldPropertyStorage[i]; - - if (!wasInline) - delete [] oldPropertyStorage; - - m_externalStorage = newPropertyStorage; -} - -ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack) -{ - JSCell::markChildren(markStack); - - markStack.append(prototype()); - - PropertyStorage storage = propertyStorage(); - size_t storageSize = m_structure->propertyStorageSize(); - markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize); -} - -// --- JSValue inlines ---------------------------- - -ALWAYS_INLINE UString JSValue::toThisString(ExecState* exec) const -{ - return isString() ? static_cast<JSString*>(asCell())->value(exec) : toThisObject(exec)->toString(exec); -} - -inline JSString* JSValue::toThisJSString(ExecState* exec) const -{ - return isString() ? static_cast<JSString*>(asCell()) : jsString(exec, toThisObject(exec)->toString(exec)); -} - -inline JSValue JSValue::toStrictThisObject(ExecState* exec) const -{ - if (!isObject()) - return *this; - return asObject(asCell())->toStrictThisObject(exec); -} - -} // namespace JSC - -#endif // JSObject_h diff --git a/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp b/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp deleted file mode 100644 index e9d6c96..0000000 --- a/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 "JSObjectWithGlobalObject.h" - -#include "JSGlobalObject.h" - -namespace JSC { - -JSObjectWithGlobalObject::JSObjectWithGlobalObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : JSObject(structure) -{ - COMPILE_ASSERT(AnonymousSlotCount == 1, AnonymousSlotCount_must_be_one); - ASSERT(!globalObject || globalObject->isGlobalObject()); - putAnonymousValue(GlobalObjectSlot, globalObject); -} - -JSGlobalObject* JSObjectWithGlobalObject::globalObject() const -{ - return asGlobalObject((getAnonymousValue(GlobalObjectSlot).asCell())); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSObjectWithGlobalObject.h b/JavaScriptCore/runtime/JSObjectWithGlobalObject.h deleted file mode 100644 index 9416a62..0000000 --- a/JavaScriptCore/runtime/JSObjectWithGlobalObject.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 JSObjectWithGlobalObject_h -#define JSObjectWithGlobalObject_h - -#include "JSObject.h" - -namespace JSC { - -class JSGlobalObject; - -class JSObjectWithGlobalObject : public JSObject { -public: - static PassRefPtr<Structure> createStructure(JSValue proto) - { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - JSGlobalObject* globalObject() const; - -protected: - JSObjectWithGlobalObject(JSGlobalObject*, NonNullPassRefPtr<Structure>); - - JSObjectWithGlobalObject(NonNullPassRefPtr<Structure> structure) - : JSObject(structure) - { - // Should only be used by JSFunction when we aquire the JSFunction vptr. - } - static const unsigned AnonymousSlotCount = JSObject::AnonymousSlotCount + 1; - static const unsigned GlobalObjectSlot = 0; -}; - -} // namespace JSC - -#endif // JSObjectWithGlobalObject_h diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp deleted file mode 100644 index a5d4da0..0000000 --- a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "JSPropertyNameIterator.h" - -#include "JSGlobalObject.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator); - -inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots) - : JSCell(exec->globalData().propertyNameIteratorStructure.get()) - , m_cachedStructure(0) - , m_numCacheableSlots(numCacheableSlots) - , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size()) - , m_jsStrings(new JSValue[m_jsStringsSize]) -{ - PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); - for (size_t i = 0; i < m_jsStringsSize; ++i) - m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring()); -} - -JSPropertyNameIterator::~JSPropertyNameIterator() -{ - if (m_cachedStructure) - m_cachedStructure->clearEnumerationCache(this); -} - -JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o) -{ - ASSERT(!o->structure()->enumerationCache() || - o->structure()->enumerationCache()->cachedStructure() != o->structure() || - o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec)); - - PropertyNameArray propertyNames(exec); - o->getPropertyNames(exec, propertyNames); - size_t numCacheableSlots = 0; - if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() && - !o->structure()->hasGetterSetterProperties() && !o->structure()->isUncacheableDictionary() && - !o->structure()->typeInfo().overridesGetPropertyNames()) - numCacheableSlots = o->structure()->propertyStorageSize(); - - JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots); - - if (o->structure()->isDictionary()) - return jsPropertyNameIterator; - - if (o->structure()->typeInfo().overridesGetPropertyNames()) - return jsPropertyNameIterator; - - size_t count = normalizePrototypeChain(exec, o); - StructureChain* structureChain = o->structure()->prototypeChain(exec); - RefPtr<Structure>* structure = structureChain->head(); - for (size_t i = 0; i < count; ++i) { - if (structure[i]->typeInfo().overridesGetPropertyNames()) - return jsPropertyNameIterator; - } - - jsPropertyNameIterator->setCachedPrototypeChain(structureChain); - jsPropertyNameIterator->setCachedStructure(o->structure()); - o->structure()->setEnumerationCache(jsPropertyNameIterator); - return jsPropertyNameIterator; -} - -JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i) -{ - JSValue& identifier = m_jsStrings[i]; - if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec)) - return identifier; - - if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec)))) - return JSValue(); - return identifier; -} - -void JSPropertyNameIterator::markChildren(MarkStack& markStack) -{ - markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h deleted file mode 100644 index 01700ac..0000000 --- a/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSPropertyNameIterator_h -#define JSPropertyNameIterator_h - -#include "JSObject.h" -#include "JSString.h" -#include "Operations.h" -#include "PropertyNameArray.h" - -namespace JSC { - - class Identifier; - class JSObject; - - class JSPropertyNameIterator : public JSCell { - friend class JIT; - - public: - static JSPropertyNameIterator* create(ExecState*, JSObject*); - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount); - } - - virtual ~JSPropertyNameIterator(); - - virtual bool isPropertyNameIterator() const { return true; } - - virtual void markChildren(MarkStack&); - - bool getOffset(size_t i, int& offset) - { - if (i >= m_numCacheableSlots) - return false; - offset = i; - return true; - } - - JSValue get(ExecState*, JSObject*, size_t i); - size_t size() { return m_jsStringsSize; } - - void setCachedStructure(Structure* structure) - { - ASSERT(!m_cachedStructure); - ASSERT(structure); - m_cachedStructure = structure; - } - Structure* cachedStructure() { return m_cachedStructure.get(); } - - void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; } - StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); } - - private: - JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot); - - RefPtr<Structure> m_cachedStructure; - RefPtr<StructureChain> m_cachedPrototypeChain; - uint32_t m_numCacheableSlots; - uint32_t m_jsStringsSize; - OwnArrayPtr<JSValue> m_jsStrings; - }; - - inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache) - { - ASSERT(!isDictionary()); - m_enumerationCache = enumerationCache; - } - - inline void Structure::clearEnumerationCache(JSPropertyNameIterator* enumerationCache) - { - m_enumerationCache.clear(enumerationCache); - } - - inline JSPropertyNameIterator* Structure::enumerationCache() - { - return m_enumerationCache.get(); - } - -} // namespace JSC - -#endif // JSPropertyNameIterator_h diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/JavaScriptCore/runtime/JSStaticScopeObject.cpp deleted file mode 100644 index 7ab1d1c..0000000 --- a/JavaScriptCore/runtime/JSStaticScopeObject.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include "JSStaticScopeObject.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject); - -void JSStaticScopeObject::markChildren(MarkStack& markStack) -{ - JSVariableObject::markChildren(markStack); - markStack.append(d()->registerStore.jsValue()); -} - -JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const -{ - return exec->globalThisValue(); -} - -JSValue JSStaticScopeObject::toStrictThisObject(ExecState*) const -{ - return jsNull(); -} - -void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&) -{ - if (symbolTablePut(propertyName, value)) - return; - - ASSERT_NOT_REACHED(); -} - -void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes) -{ - if (symbolTablePutWithAttributes(propertyName, value, attributes)) - return; - - ASSERT_NOT_REACHED(); -} - -bool JSStaticScopeObject::isDynamicScope(bool&) const -{ - return false; -} - -JSStaticScopeObject::~JSStaticScopeObject() -{ - ASSERT(d()); - delete d(); -} - -inline bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot& slot) -{ - return symbolTableGet(propertyName, slot); -} - -} diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h deleted file mode 100644 index e69356a..0000000 --- a/JavaScriptCore/runtime/JSStaticScopeObject.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSStaticScopeObject_h -#define JSStaticScopeObject_h - -#include "JSVariableObject.h" - -namespace JSC{ - - class JSStaticScopeObject : public JSVariableObject { - protected: - using JSVariableObject::JSVariableObjectData; - struct JSStaticScopeObjectData : public JSVariableObjectData { - JSStaticScopeObjectData() - : JSVariableObjectData(&symbolTable, ®isterStore + 1) - { - } - SymbolTable symbolTable; - Register registerStore; - }; - - public: - JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue value, unsigned attributes) - : JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData()) - { - d()->registerStore = value; - symbolTable().add(ident.impl(), SymbolTableEntry(-1, attributes)); - } - virtual ~JSStaticScopeObject(); - virtual void markChildren(MarkStack&); - bool isDynamicScope(bool& requiresDynamicChecks) const; - virtual JSObject* toThisObject(ExecState*) const; - virtual JSValue toStrictThisObject(ExecState*) const; - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); - void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes); - - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; - - private: - JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); } - }; - -} - -#endif // JSStaticScopeObject_h diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp deleted file mode 100644 index ba28139..0000000 --- a/JavaScriptCore/runtime/JSString.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSString.h" - -#include "JSGlobalObject.h" -#include "JSGlobalObjectFunctions.h" -#include "JSObject.h" -#include "Operations.h" -#include "StringObject.h" -#include "StringPrototype.h" - -namespace JSC { - -static const unsigned substringFromRopeCutoff = 4; - -// Overview: this methods converts a JSString from holding a string in rope form -// down to a simple UString representation. It does so by building up the string -// backwards, since we want to avoid recursion, we expect that the tree structure -// representing the rope is likely imbalanced with more nodes down the left side -// (since appending to the string is likely more common) - and as such resolving -// in this fashion should minimize work queue size. (If we built the queue forwards -// we would likely have to place all of the constituent StringImpls into the -// Vector before performing any concatenation, but by working backwards we likely -// only fill the queue with the number of substrings at any given level in a -// rope-of-ropes.) -void JSString::resolveRope(ExecState* exec) const -{ - ASSERT(isRope()); - - // Allocate the buffer to hold the final string, position initially points to the end. - UChar* buffer; - if (PassRefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) - m_value = newImpl; - else { - for (unsigned i = 0; i < m_fiberCount; ++i) { - RopeImpl::deref(m_other.m_fibers[i]); - m_other.m_fibers[i] = 0; - } - m_fiberCount = 0; - ASSERT(!isRope()); - ASSERT(m_value == UString()); - if (exec) - throwOutOfMemoryError(exec); - return; - } - UChar* position = buffer + m_length; - - // Start with the current RopeImpl. - Vector<RopeImpl::Fiber, 32> workQueue; - RopeImpl::Fiber currentFiber; - for (unsigned i = 0; i < (m_fiberCount - 1); ++i) - workQueue.append(m_other.m_fibers[i]); - currentFiber = m_other.m_fibers[m_fiberCount - 1]; - while (true) { - if (RopeImpl::isRope(currentFiber)) { - RopeImpl* rope = static_cast<RopeImpl*>(currentFiber); - // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber' - // (we will be working backwards over the rope). - unsigned fiberCountMinusOne = rope->fiberCount() - 1; - for (unsigned i = 0; i < fiberCountMinusOne; ++i) - workQueue.append(rope->fibers()[i]); - currentFiber = rope->fibers()[fiberCountMinusOne]; - } else { - StringImpl* string = static_cast<StringImpl*>(currentFiber); - unsigned length = string->length(); - position -= length; - StringImpl::copyChars(position, string->characters(), length); - - // Was this the last item in the work queue? - if (workQueue.isEmpty()) { - // Create a string from the UChar buffer, clear the rope RefPtr. - ASSERT(buffer == position); - for (unsigned i = 0; i < m_fiberCount; ++i) { - RopeImpl::deref(m_other.m_fibers[i]); - m_other.m_fibers[i] = 0; - } - m_fiberCount = 0; - - ASSERT(!isRope()); - return; - } - - // No! - set the next item up to process. - currentFiber = workQueue.last(); - workQueue.removeLast(); - } - } -} - -// This function construsts a substring out of a rope without flattening by reusing the existing fibers. -// This can reduce memory usage substantially. Since traversing ropes is slow the function will revert -// back to flattening if the rope turns out to be long. -JSString* JSString::substringFromRope(ExecState* exec, unsigned substringStart, unsigned substringLength) -{ - ASSERT(isRope()); - ASSERT(substringLength); - - JSGlobalData* globalData = &exec->globalData(); - - UString substringFibers[3]; - - unsigned fiberCount = 0; - unsigned substringFiberCount = 0; - unsigned substringEnd = substringStart + substringLength; - unsigned fiberEnd = 0; - - RopeIterator end; - for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { - ++fiberCount; - StringImpl* fiberString = *it; - unsigned fiberStart = fiberEnd; - fiberEnd = fiberStart + fiberString->length(); - if (fiberEnd <= substringStart) - continue; - unsigned copyStart = std::max(substringStart, fiberStart); - unsigned copyEnd = std::min(substringEnd, fiberEnd); - if (copyStart == fiberStart && copyEnd == fiberEnd) - substringFibers[substringFiberCount++] = UString(fiberString); - else - substringFibers[substringFiberCount++] = UString(StringImpl::create(fiberString, copyStart - fiberStart, copyEnd - copyStart)); - if (fiberEnd >= substringEnd) - break; - if (fiberCount > substringFromRopeCutoff || substringFiberCount >= 3) { - // This turned out to be a really inefficient rope. Just flatten it. - resolveRope(exec); - return jsSubstring(&exec->globalData(), m_value, substringStart, substringLength); - } - } - ASSERT(substringFiberCount && substringFiberCount <= 3); - - if (substringLength == 1) { - ASSERT(substringFiberCount == 1); - UChar c = substringFibers[0].characters()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - if (substringFiberCount == 1) - return new (globalData) JSString(globalData, substringFibers[0]); - if (substringFiberCount == 2) - return new (globalData) JSString(globalData, substringFibers[0], substringFibers[1]); - return new (globalData) JSString(globalData, substringFibers[0], substringFibers[1], substringFibers[2]); -} - -JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement) -{ - if (!isRope()) { - size_t matchPosition = m_value.find(character); - if (matchPosition == notFound) - return JSValue(this); - return jsString(exec, m_value.substringSharingImpl(0, matchPosition), replacement, m_value.substringSharingImpl(matchPosition + 1)); - } - - RopeIterator end; - - // Count total fibers and find matching string. - size_t fiberCount = 0; - StringImpl* matchString = 0; - size_t matchPosition = notFound; - for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { - ++fiberCount; - if (matchString) - continue; - - StringImpl* string = *it; - matchPosition = string->find(character); - if (matchPosition == notFound) - continue; - matchString = string; - } - - if (!matchString) - return this; - - RopeBuilder builder(replacement.length() ? fiberCount + 2 : fiberCount + 1); - if (UNLIKELY(builder.isOutOfMemory())) - return throwOutOfMemoryError(exec); - - for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { - StringImpl* string = *it; - if (string != matchString) { - builder.append(UString(string)); - continue; - } - - builder.append(UString(string).substringSharingImpl(0, matchPosition)); - if (replacement.length()) - builder.append(replacement); - builder.append(UString(string).substringSharingImpl(matchPosition + 1)); - matchString = 0; - } - - JSGlobalData* globalData = &exec->globalData(); - return JSValue(new (globalData) JSString(globalData, builder.release())); -} - -JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i) -{ - ASSERT(isRope()); - resolveRope(exec); - // Return a safe no-value result, this should never be used, since the excetion will be thrown. - if (exec->exception()) - return jsString(exec, ""); - ASSERT(!isRope()); - ASSERT(i < m_value.length()); - return jsSingleCharacterSubstring(exec, m_value, i); -} - -JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const -{ - return const_cast<JSString*>(this); -} - -bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) -{ - result = this; - number = jsToNumber(value(exec)); - return false; -} - -bool JSString::toBoolean(ExecState*) const -{ - return m_length; -} - -double JSString::toNumber(ExecState* exec) const -{ - return jsToNumber(value(exec)); -} - -UString JSString::toString(ExecState* exec) const -{ - return value(exec); -} - -inline StringObject* StringObject::create(ExecState* exec, JSString* string) -{ - return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string); -} - -JSObject* JSString::toObject(ExecState* exec) const -{ - return StringObject::create(exec, const_cast<JSString*>(this)); -} - -JSObject* JSString::toThisObject(ExecState* exec) const -{ - return StringObject::create(exec, const_cast<JSString*>(this)); -} - -bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - // The semantics here are really getPropertySlot, not getOwnPropertySlot. - // This function should only be called by JSValue::get. - if (getStringPropertySlot(exec, propertyName, slot)) - return true; - if (propertyName == exec->propertyNames().underscoreProto) { - slot.setValue(exec->lexicalGlobalObject()->stringPrototype()); - return true; - } - slot.setBase(this); - JSObject* object; - for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) { - object = asObject(prototype); - if (object->getOwnPropertySlot(exec, propertyName, slot)) - return true; - } - slot.setUndefined(); - return true; -} - -bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (propertyName == exec->propertyNames().length) { - descriptor.setDescriptor(jsNumber(m_length), DontEnum | DontDelete | ReadOnly); - return true; - } - - bool isStrictUInt32; - unsigned i = propertyName.toUInt32(isStrictUInt32); - if (isStrictUInt32 && i < m_length) { - descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly); - return true; - } - - return false; -} - -bool JSString::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (getStringPropertyDescriptor(exec, propertyName, descriptor)) - return true; - if (propertyName != exec->propertyNames().underscoreProto) - return false; - descriptor.setDescriptor(exec->lexicalGlobalObject()->stringPrototype(), DontEnum); - return true; -} - -bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) -{ - // The semantics here are really getPropertySlot, not getOwnPropertySlot. - // This function should only be called by JSValue::get. - if (getStringPropertySlot(exec, propertyName, slot)) - return true; - return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h deleted file mode 100644 index fefffde..0000000 --- a/JavaScriptCore/runtime/JSString.h +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSString_h -#define JSString_h - -#include "CallFrame.h" -#include "CommonIdentifiers.h" -#include "Identifier.h" -#include "JSNumberCell.h" -#include "PropertyDescriptor.h" -#include "PropertySlot.h" -#include "RopeImpl.h" - -namespace JSC { - - class JSString; - - JSString* jsEmptyString(JSGlobalData*); - JSString* jsEmptyString(ExecState*); - JSString* jsString(JSGlobalData*, const UString&); // returns empty string if passed null string - JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string - - JSString* jsSingleCharacterString(JSGlobalData*, UChar); - JSString* jsSingleCharacterString(ExecState*, UChar); - JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset); - JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length); - JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length); - - // Non-trivial strings are two or more characters long. - // These functions are faster than just calling jsString. - JSString* jsNontrivialString(JSGlobalData*, const UString&); - JSString* jsNontrivialString(ExecState*, const UString&); - JSString* jsNontrivialString(JSGlobalData*, const char*); - JSString* jsNontrivialString(ExecState*, const char*); - - // Should be used for strings that are owned by an object that will - // likely outlive the JSValue this makes, such as the parse tree or a - // DOM object that contains a UString - JSString* jsOwnedString(JSGlobalData*, const UString&); - JSString* jsOwnedString(ExecState*, const UString&); - - typedef void (*JSStringFinalizerCallback)(JSString*, void* context); - JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context); - - class JS_EXPORTCLASS JSString : public JSCell { - public: - friend class JIT; - friend class JSGlobalData; - friend class SpecializedThunkJIT; - friend struct ThunkHelpers; - - class RopeBuilder { - public: - RopeBuilder(unsigned fiberCount) - : m_index(0) - , m_rope(RopeImpl::tryCreateUninitialized(fiberCount)) - { - } - - bool isOutOfMemory() { return !m_rope; } - - void append(RopeImpl::Fiber& fiber) - { - ASSERT(m_rope); - m_rope->initializeFiber(m_index, fiber); - } - void append(const UString& string) - { - ASSERT(m_rope); - m_rope->initializeFiber(m_index, string.impl()); - } - void append(JSString* jsString) - { - if (jsString->isRope()) { - for (unsigned i = 0; i < jsString->m_fiberCount; ++i) - append(jsString->m_other.m_fibers[i]); - } else - append(jsString->string()); - } - - PassRefPtr<RopeImpl> release() - { - ASSERT(m_index == m_rope->fiberCount()); - return m_rope.release(); - } - - unsigned length() { return m_rope->length(); } - - private: - unsigned m_index; - RefPtr<RopeImpl> m_rope; - }; - - class RopeIterator { - public: - RopeIterator() { } - - RopeIterator(RopeImpl::Fiber* fibers, size_t fiberCount) - { - ASSERT(fiberCount); - m_workQueue.append(WorkItem(fibers, fiberCount)); - skipRopes(); - } - - RopeIterator& operator++() - { - WorkItem& item = m_workQueue.last(); - ASSERT(!RopeImpl::isRope(item.fibers[item.i])); - if (++item.i == item.fiberCount) - m_workQueue.removeLast(); - skipRopes(); - return *this; - } - - StringImpl* operator*() - { - WorkItem& item = m_workQueue.last(); - RopeImpl::Fiber fiber = item.fibers[item.i]; - ASSERT(!RopeImpl::isRope(fiber)); - return static_cast<StringImpl*>(fiber); - } - - bool operator!=(const RopeIterator& other) const - { - return m_workQueue != other.m_workQueue; - } - - private: - struct WorkItem { - WorkItem(RopeImpl::Fiber* fibers, size_t fiberCount) - : fibers(fibers) - , fiberCount(fiberCount) - , i(0) - { - } - - bool operator!=(const WorkItem& other) const - { - return fibers != other.fibers || fiberCount != other.fiberCount || i != other.i; - } - - RopeImpl::Fiber* fibers; - size_t fiberCount; - size_t i; - }; - - void skipRopes() - { - if (m_workQueue.isEmpty()) - return; - - while (1) { - WorkItem& item = m_workQueue.last(); - RopeImpl::Fiber fiber = item.fibers[item.i]; - if (!RopeImpl::isRope(fiber)) - break; - RopeImpl* rope = static_cast<RopeImpl*>(fiber); - if (++item.i == item.fiberCount) - m_workQueue.removeLast(); - m_workQueue.append(WorkItem(rope->fibers(), rope->fiberCount())); - } - } - - Vector<WorkItem, 16> m_workQueue; - }; - - ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value) - : JSCell(globalData->stringStructure.get()) - , m_length(value.length()) - , m_value(value) - , m_fiberCount(0) - { - ASSERT(!m_value.isNull()); - Heap::heap(this)->reportExtraMemoryCost(value.impl()->cost()); - } - - enum HasOtherOwnerType { HasOtherOwner }; - JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType) - : JSCell(globalData->stringStructure.get()) - , m_length(value.length()) - , m_value(value) - , m_fiberCount(0) - { - ASSERT(!m_value.isNull()); - } - JSString(JSGlobalData* globalData, PassRefPtr<StringImpl> value, HasOtherOwnerType) - : JSCell(globalData->stringStructure.get()) - , m_length(value->length()) - , m_value(value) - , m_fiberCount(0) - { - ASSERT(!m_value.isNull()); - } - JSString(JSGlobalData* globalData, PassRefPtr<RopeImpl> rope) - : JSCell(globalData->stringStructure.get()) - , m_length(rope->length()) - , m_fiberCount(1) - { - m_other.m_fibers[0] = rope.leakRef(); - } - // This constructor constructs a new string by concatenating s1 & s2. - // This should only be called with fiberCount <= 3. - JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, JSString* s2) - : JSCell(globalData->stringStructure.get()) - , m_length(s1->length() + s2->length()) - , m_fiberCount(fiberCount) - { - ASSERT(fiberCount <= s_maxInternalRopeLength); - unsigned index = 0; - appendStringInConstruct(index, s1); - appendStringInConstruct(index, s2); - ASSERT(fiberCount == index); - } - // This constructor constructs a new string by concatenating s1 & s2. - // This should only be called with fiberCount <= 3. - JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, const UString& u2) - : JSCell(globalData->stringStructure.get()) - , m_length(s1->length() + u2.length()) - , m_fiberCount(fiberCount) - { - ASSERT(fiberCount <= s_maxInternalRopeLength); - unsigned index = 0; - appendStringInConstruct(index, s1); - appendStringInConstruct(index, u2); - ASSERT(fiberCount == index); - } - // This constructor constructs a new string by concatenating s1 & s2. - // This should only be called with fiberCount <= 3. - JSString(JSGlobalData* globalData, unsigned fiberCount, const UString& u1, JSString* s2) - : JSCell(globalData->stringStructure.get()) - , m_length(u1.length() + s2->length()) - , m_fiberCount(fiberCount) - { - ASSERT(fiberCount <= s_maxInternalRopeLength); - unsigned index = 0; - appendStringInConstruct(index, u1); - appendStringInConstruct(index, s2); - ASSERT(fiberCount == index); - } - // This constructor constructs a new string by concatenating v1, v2 & v3. - // This should only be called with fiberCount <= 3 ... which since every - // value must require a fiberCount of at least one implies that the length - // for each value must be exactly 1! - JSString(ExecState* exec, JSValue v1, JSValue v2, JSValue v3) - : JSCell(exec->globalData().stringStructure.get()) - , m_length(0) - , m_fiberCount(s_maxInternalRopeLength) - { - unsigned index = 0; - appendValueInConstructAndIncrementLength(exec, index, v1); - appendValueInConstructAndIncrementLength(exec, index, v2); - appendValueInConstructAndIncrementLength(exec, index, v3); - ASSERT(index == s_maxInternalRopeLength); - } - - // This constructor constructs a new string by concatenating u1 & u2. - JSString(JSGlobalData* globalData, const UString& u1, const UString& u2) - : JSCell(globalData->stringStructure.get()) - , m_length(u1.length() + u2.length()) - , m_fiberCount(2) - { - unsigned index = 0; - appendStringInConstruct(index, u1); - appendStringInConstruct(index, u2); - ASSERT(index <= s_maxInternalRopeLength); - } - - // This constructor constructs a new string by concatenating u1, u2 & u3. - JSString(JSGlobalData* globalData, const UString& u1, const UString& u2, const UString& u3) - : JSCell(globalData->stringStructure.get()) - , m_length(u1.length() + u2.length() + u3.length()) - , m_fiberCount(s_maxInternalRopeLength) - { - unsigned index = 0; - appendStringInConstruct(index, u1); - appendStringInConstruct(index, u2); - appendStringInConstruct(index, u3); - ASSERT(index <= s_maxInternalRopeLength); - } - - JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context) - : JSCell(globalData->stringStructure.get()) - , m_length(value.length()) - , m_value(value) - , m_fiberCount(0) - { - ASSERT(!m_value.isNull()); - // nasty hack because we can't union non-POD types - m_other.m_finalizerCallback = finalizer; - m_other.m_finalizerContext = context; - Heap::heap(this)->reportExtraMemoryCost(value.impl()->cost()); - } - - ~JSString() - { - ASSERT(vptr() == JSGlobalData::jsStringVPtr); - for (unsigned i = 0; i < m_fiberCount; ++i) - RopeImpl::deref(m_other.m_fibers[i]); - - if (!m_fiberCount && m_other.m_finalizerCallback) - m_other.m_finalizerCallback(this, m_other.m_finalizerContext); - } - - const UString& value(ExecState* exec) const - { - if (isRope()) - resolveRope(exec); - return m_value; - } - const UString& tryGetValue() const - { - if (isRope()) - resolveRope(0); - return m_value; - } - unsigned length() { return m_length; } - - bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&); - - bool canGetIndex(unsigned i) { return i < m_length; } - JSString* getIndex(ExecState*, unsigned); - JSString* getIndexSlowCase(ExecState*, unsigned); - - JSValue replaceCharacter(ExecState*, UChar, const UString& replacement); - - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); } - - private: - enum VPtrStealingHackType { VPtrStealingHack }; - JSString(VPtrStealingHackType) - : JSCell(0) - , m_fiberCount(0) - { - } - - void resolveRope(ExecState*) const; - JSString* substringFromRope(ExecState*, unsigned offset, unsigned length); - - void appendStringInConstruct(unsigned& index, const UString& string) - { - StringImpl* impl = string.impl(); - impl->ref(); - m_other.m_fibers[index++] = impl; - } - - void appendStringInConstruct(unsigned& index, JSString* jsString) - { - if (jsString->isRope()) { - for (unsigned i = 0; i < jsString->m_fiberCount; ++i) { - RopeImpl::Fiber fiber = jsString->m_other.m_fibers[i]; - fiber->ref(); - m_other.m_fibers[index++] = fiber; - } - } else - appendStringInConstruct(index, jsString->string()); - } - - void appendValueInConstructAndIncrementLength(ExecState* exec, unsigned& index, JSValue v) - { - if (v.isString()) { - ASSERT(v.asCell()->isString()); - JSString* s = static_cast<JSString*>(v.asCell()); - ASSERT(s->fiberCount() == 1); - appendStringInConstruct(index, s); - m_length += s->length(); - } else { - UString u(v.toString(exec)); - StringImpl* impl = u.impl(); - impl->ref(); - m_other.m_fibers[index++] = impl; - m_length += u.length(); - } - } - - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value); - virtual bool toBoolean(ExecState*) const; - virtual double toNumber(ExecState*) const; - virtual JSObject* toObject(ExecState*) const; - virtual UString toString(ExecState*) const; - - virtual JSObject* toThisObject(ExecState*) const; - - // Actually getPropertySlot, not getOwnPropertySlot (see JSCell). - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - static const unsigned s_maxInternalRopeLength = 3; - - // A string is represented either by a UString or a RopeImpl. - unsigned m_length; - mutable UString m_value; - mutable unsigned m_fiberCount; - // This structure exists to support a temporary workaround for a GC issue. - struct JSStringFinalizerStruct { - JSStringFinalizerStruct() : m_finalizerCallback(0) {} - union { - mutable FixedArray<RopeImpl::Fiber, s_maxInternalRopeLength> m_fibers; - struct { - JSStringFinalizerCallback m_finalizerCallback; - void* m_finalizerContext; - }; - }; - } m_other; - - bool isRope() const { return m_fiberCount; } - UString& string() { ASSERT(!isRope()); return m_value; } - unsigned fiberCount() { return m_fiberCount ? m_fiberCount : 1; } - - friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2); - friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2); - friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2); - friend JSValue jsString(ExecState* exec, Register* strings, unsigned count); - friend JSValue jsString(ExecState* exec, JSValue thisValue); - friend JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context); - friend JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length); - }; - - JSString* asString(JSValue); - - // When an object is created from a different DLL, MSVC changes vptr to a "local" one right after invoking a constructor, - // see <http://groups.google.com/group/microsoft.public.vc.language/msg/55cdcefeaf770212>. - // This breaks isJSString(), and we don't need that hack anyway, so we change vptr back to primary one. - // The below function must be called by any inline function that invokes a JSString constructor. -#if COMPILER(MSVC) && !defined(BUILDING_JavaScriptCore) - inline JSString* fixupVPtr(JSGlobalData* globalData, JSString* string) { string->setVPtr(globalData->jsStringVPtr); return string; } -#else - inline JSString* fixupVPtr(JSGlobalData*, JSString* string) { return string; } -#endif - - inline JSString* asString(JSValue value) - { - ASSERT(value.asCell()->isString()); - return static_cast<JSString*>(value.asCell()); - } - - inline JSString* jsEmptyString(JSGlobalData* globalData) - { - return globalData->smallStrings.emptyString(globalData); - } - - inline JSString* jsSingleCharacterString(JSGlobalData* globalData, UChar c) - { - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1))); - } - - inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) - { - JSGlobalData* globalData = &exec->globalData(); - ASSERT(offset < static_cast<unsigned>(s.length())); - UChar c = s.characters()[offset]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, 1)))); - } - - inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s) - { - ASSERT(s); - ASSERT(s[0]); - ASSERT(s[1]); - return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); - } - - inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s) - { - ASSERT(s.length() > 1); - return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); - } - - inline JSString* JSString::getIndex(ExecState* exec, unsigned i) - { - ASSERT(canGetIndex(i)); - if (isRope()) - return getIndexSlowCase(exec, i); - ASSERT(i < m_value.length()); - return jsSingleCharacterSubstring(exec, m_value, i); - } - - inline JSString* jsString(JSGlobalData* globalData, const UString& s) - { - int size = s.length(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.characters()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); - } - - inline JSString* jsStringWithFinalizer(ExecState* exec, const UString& s, JSStringFinalizerCallback callback, void* context) - { - ASSERT(s.length() && (s.length() > 1 || s.characters()[0] > 0xFF)); - JSGlobalData* globalData = &exec->globalData(); - return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context)); - } - - inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length) - { - ASSERT(offset <= static_cast<unsigned>(s->length())); - ASSERT(length <= static_cast<unsigned>(s->length())); - ASSERT(offset + length <= static_cast<unsigned>(s->length())); - JSGlobalData* globalData = &exec->globalData(); - if (!length) - return globalData->smallStrings.emptyString(globalData); - if (s->isRope()) - return s->substringFromRope(exec, offset, length); - return jsSubstring(globalData, s->m_value, offset, length); - } - - inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) - { - ASSERT(offset <= static_cast<unsigned>(s.length())); - ASSERT(length <= static_cast<unsigned>(s.length())); - ASSERT(offset + length <= static_cast<unsigned>(s.length())); - if (!length) - return globalData->smallStrings.emptyString(globalData); - if (length == 1) { - UChar c = s.characters()[offset]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, length)), JSString::HasOtherOwner)); - } - - inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) - { - int size = s.length(); - if (!size) - return globalData->smallStrings.emptyString(globalData); - if (size == 1) { - UChar c = s.characters()[0]; - if (c <= 0xFF) - return globalData->smallStrings.singleCharacterString(globalData, c); - } - return fixupVPtr(globalData, new (globalData) JSString(globalData, s, JSString::HasOtherOwner)); - } - - inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); } - inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } - inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } - inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); } - inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); } - inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); } - inline JSString* jsOwnedString(ExecState* exec, const UString& s) { return jsOwnedString(&exec->globalData(), s); } - - ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) - { - if (propertyName == exec->propertyNames().length) { - slot.setValue(jsNumber(m_length)); - return true; - } - - bool isStrictUInt32; - unsigned i = propertyName.toUInt32(isStrictUInt32); - if (isStrictUInt32 && i < m_length) { - slot.setValue(getIndex(exec, i)); - return true; - } - - return false; - } - - ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) - { - if (propertyName < m_length) { - slot.setValue(getIndex(exec, propertyName)); - return true; - } - - return false; - } - - inline bool isJSString(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsStringVPtr; } - - // --- JSValue inlines ---------------------------- - - inline UString JSValue::toString(ExecState* exec) const - { - if (isString()) - return static_cast<JSString*>(asCell())->value(exec); - if (isInt32()) - return exec->globalData().numericStrings.add(asInt32()); - if (isDouble()) - return exec->globalData().numericStrings.add(asDouble()); - if (isTrue()) - return "true"; - if (isFalse()) - return "false"; - if (isNull()) - return "null"; - if (isUndefined()) - return "undefined"; - ASSERT(isCell()); - return asCell()->toString(exec); - } - - inline UString JSValue::toPrimitiveString(ExecState* exec) const - { - if (isString()) - return static_cast<JSString*>(asCell())->value(exec); - if (isInt32()) - return exec->globalData().numericStrings.add(asInt32()); - if (isDouble()) - return exec->globalData().numericStrings.add(asDouble()); - if (isTrue()) - return "true"; - if (isFalse()) - return "false"; - if (isNull()) - return "null"; - if (isUndefined()) - return "undefined"; - ASSERT(isCell()); - return asCell()->toPrimitive(exec, NoPreference).toString(exec); - } - -} // namespace JSC - -#endif // JSString_h diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h deleted file mode 100644 index 49d4a63..0000000 --- a/JavaScriptCore/runtime/JSStringBuilder.h +++ /dev/null @@ -1,134 +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 JSStringBuilder_h -#define JSStringBuilder_h - -#include "ExceptionHelpers.h" -#include "JSString.h" -#include "UStringConcatenate.h" -#include "Vector.h" - -namespace JSC { - -class JSStringBuilder { -public: - JSStringBuilder() - : m_okay(true) - { - } - - void append(const UChar u) - { - m_okay &= buffer.tryAppend(&u, 1); - } - - void append(const char* str) - { - append(str, strlen(str)); - } - - void append(const char* str, size_t len) - { - m_okay &= buffer.tryReserveCapacity(buffer.size() + len); - for (size_t i = 0; i < len; i++) { - UChar u = static_cast<unsigned char>(str[i]); - m_okay &= buffer.tryAppend(&u, 1); - } - } - - void append(const UChar* str, size_t len) - { - m_okay &= buffer.tryAppend(str, len); - } - - void append(const UString& str) - { - m_okay &= buffer.tryAppend(str.characters(), str.length()); - } - - JSValue build(ExecState* exec) - { - if (!m_okay) - return throwOutOfMemoryError(exec); - buffer.shrinkToFit(); - if (!buffer.data()) - return throwOutOfMemoryError(exec); - return jsString(exec, UString::adopt(buffer)); - } - -protected: - Vector<UChar, 64> buffer; - bool m_okay; -}; - -template<typename StringType1, typename StringType2> -inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2) -{ - PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2); - if (!result) - return throwOutOfMemoryError(exec); - return jsNontrivialString(exec, result); -} - -template<typename StringType1, typename StringType2, typename StringType3> -inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3) -{ - PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3); - if (!result) - return throwOutOfMemoryError(exec); - return jsNontrivialString(exec, result); -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> -inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) -{ - PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4); - if (!result) - return throwOutOfMemoryError(exec); - return jsNontrivialString(exec, result); -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> -inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) -{ - PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5); - if (!result) - return throwOutOfMemoryError(exec); - return jsNontrivialString(exec, result); -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> -inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) -{ - PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6); - if (!result) - return throwOutOfMemoryError(exec); - return jsNontrivialString(exec, result); -} - -} - -#endif diff --git a/JavaScriptCore/runtime/JSType.h b/JavaScriptCore/runtime/JSType.h deleted file mode 100644 index 882b218..0000000 --- a/JavaScriptCore/runtime/JSType.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSType_h -#define JSType_h - -namespace JSC { - - /** - * Primitive types - */ - enum JSType { - UnspecifiedType = 0, - UndefinedType = 1, - BooleanType = 2, - NumberType = 3, - NullType = 4, - StringType = 5, - // The CompoundType value must come before any JSType that may have children - CompoundType = 6, - ObjectType = 7, - GetterSetterType = 8 - }; - -} // namespace JSC - -#endif diff --git a/JavaScriptCore/runtime/JSTypeInfo.h b/JavaScriptCore/runtime/JSTypeInfo.h deleted file mode 100644 index e225bc7..0000000 --- a/JavaScriptCore/runtime/JSTypeInfo.h +++ /dev/null @@ -1,80 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSTypeInfo_h -#define JSTypeInfo_h - -// This file would be called TypeInfo.h, but that conflicts with <typeinfo.h> -// in the STL on systems without case-sensitive file systems. - -#include "JSType.h" - -namespace JSC { - - // WebCore uses MasqueradesAsUndefined to make document.all and style.filter undetectable. - static const unsigned MasqueradesAsUndefined = 1; - static const unsigned ImplementsHasInstance = 1 << 1; - static const unsigned OverridesHasInstance = 1 << 2; - static const unsigned ImplementsDefaultHasInstance = 1 << 3; - static const unsigned NeedsThisConversion = 1 << 4; - static const unsigned OverridesGetOwnPropertySlot = 1 << 5; - static const unsigned OverridesMarkChildren = 1 << 6; - static const unsigned OverridesGetPropertyNames = 1 << 7; - - class TypeInfo { - friend class JIT; - public: - TypeInfo(JSType type, unsigned flags = 0) - : m_type(type) - { - ASSERT(flags <= 0xFF); - ASSERT(type <= 0xFF); - // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance) - if ((flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance) - m_flags = flags | ImplementsDefaultHasInstance; - else - m_flags = flags; - } - - JSType type() const { return (JSType)m_type; } - - bool masqueradesAsUndefined() const { return m_flags & MasqueradesAsUndefined; } - bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; } - bool overridesHasInstance() const { return m_flags & OverridesHasInstance; } - bool needsThisConversion() const { return m_flags & NeedsThisConversion; } - bool overridesGetOwnPropertySlot() const { return m_flags & OverridesGetOwnPropertySlot; } - bool overridesMarkChildren() const { return m_flags & OverridesMarkChildren; } - bool overridesGetPropertyNames() const { return m_flags & OverridesGetPropertyNames; } - unsigned flags() const { return m_flags; } - - private: - unsigned char m_type; - unsigned char m_flags; - }; - -} - -#endif // JSTypeInfo_h diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp deleted file mode 100644 index f4662db..0000000 --- a/JavaScriptCore/runtime/JSValue.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSValue.h" - -#include "BooleanConstructor.h" -#include "BooleanPrototype.h" -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSGlobalObject.h" -#include "JSFunction.h" -#include "JSNotAnObject.h" -#include "NumberObject.h" -#include <wtf/MathExtras.h> -#include <wtf/StringExtras.h> - -namespace JSC { - -static const double D32 = 4294967296.0; - -// ECMA 9.4 -double JSValue::toInteger(ExecState* exec) const -{ - if (isInt32()) - return asInt32(); - double d = toNumber(exec); - return isnan(d) ? 0.0 : trunc(d); -} - -double JSValue::toIntegerPreserveNaN(ExecState* exec) const -{ - if (isInt32()) - return asInt32(); - return trunc(toNumber(exec)); -} - -JSObject* JSValue::toObjectSlowCase(ExecState* exec) const -{ - ASSERT(!isCell()); - - if (isInt32() || isDouble()) - return constructNumber(exec, asValue()); - if (isTrue() || isFalse()) - return constructBooleanFromImmediateBoolean(exec, asValue()); - - ASSERT(isUndefinedOrNull()); - throwError(exec, createNotAnObjectError(exec, *this)); - return new (exec) JSNotAnObject(exec); -} - -JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const -{ - ASSERT(!isCell()); - - if (isInt32() || isDouble()) - return constructNumber(exec, asValue()); - if (isTrue() || isFalse()) - return constructBooleanFromImmediateBoolean(exec, asValue()); - ASSERT(isUndefinedOrNull()); - return exec->globalThisValue(); -} - -JSObject* JSValue::synthesizeObject(ExecState* exec) const -{ - ASSERT(!isCell()); - if (isNumber()) - return constructNumber(exec, asValue()); - if (isBoolean()) - return constructBooleanFromImmediateBoolean(exec, asValue()); - - ASSERT(isUndefinedOrNull()); - throwError(exec, createNotAnObjectError(exec, *this)); - return new (exec) JSNotAnObject(exec); -} - -JSObject* JSValue::synthesizePrototype(ExecState* exec) const -{ - ASSERT(!isCell()); - if (isNumber()) - return exec->lexicalGlobalObject()->numberPrototype(); - if (isBoolean()) - return exec->lexicalGlobalObject()->booleanPrototype(); - - ASSERT(isUndefinedOrNull()); - throwError(exec, createNotAnObjectError(exec, *this)); - return new (exec) JSNotAnObject(exec); -} - -#ifndef NDEBUG -char* JSValue::description() -{ - static const size_t size = 32; - static char description[size]; - - if (!*this) - snprintf(description, size, "<JSValue()>"); - else if (isInt32()) - snprintf(description, size, "Int32: %d", asInt32()); - else if (isDouble()) - snprintf(description, size, "Double: %lf", asDouble()); - else if (isCell()) - snprintf(description, size, "Cell: %p", asCell()); - else if (isTrue()) - snprintf(description, size, "True"); - else if (isFalse()) - snprintf(description, size, "False"); - else if (isNull()) - snprintf(description, size, "Null"); - else if (isUndefined()) - snprintf(description, size, "Undefined"); - else - snprintf(description, size, "INVALID"); - - return description; -} -#endif - -// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec. -// Note that this operation is identical to ToUInt32 other than to interpretation -// of the resulting bit-pattern (as such this metod is also called to implement -// ToUInt32). -// -// The operation can be descibed as round towards zero, then select the 32 least -// bits of the resulting value in 2s-complement representation. -int32_t toInt32(double number) -{ - int64_t bits = WTF::bitwise_cast<int64_t>(number); - int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff; - - // If exponent < 0 there will be no bits to the left of the decimal point - // after rounding; if the exponent is > 83 then no bits of precision can be - // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits - // of fractional precision). - // Note this case handles 0, -0, and all infinte, NaN, & denormal value. - if (exp < 0 || exp > 83) - return 0; - - // Select the appropriate 32-bits from the floating point mantissa. If the - // exponent is 52 then the bits we need to select are already aligned to the - // lowest bits of the 64-bit integer representation of tghe number, no need - // to shift. If the exponent is greater than 52 we need to shift the value - // left by (exp - 52), if the value is less than 52 we need to shift right - // accordingly. - int32_t result = (exp > 52) - ? static_cast<int32_t>(bits << (exp - 52)) - : static_cast<int32_t>(bits >> (52 - exp)); - - // IEEE-754 double precision values are stored omitting an implicit 1 before - // the decimal point; we need to reinsert this now. We may also the shifted - // invalid bits into the result that are not a part of the mantissa (the sign - // and exponent bits from the floatingpoint representation); mask these out. - if (exp < 32) { - int32_t missingOne = 1 << exp; - result &= missingOne - 1; - result += missingOne; - } - - // If the input value was negative (we could test either 'number' or 'bits', - // but testing 'bits' is likely faster) invert the result appropriately. - return bits < 0 ? -result : result; -} - -NEVER_INLINE double nonInlineNaN() -{ -#if OS(SYMBIAN) - return nanval(); -#else - return std::numeric_limits<double>::quiet_NaN(); -#endif -} - -bool JSValue::isValidCallee() -{ - return asObject(asObject(asCell())->getAnonymousValue(0))->isGlobalObject(); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h deleted file mode 100644 index dc54f40..0000000 --- a/JavaScriptCore/runtime/JSValue.h +++ /dev/null @@ -1,770 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSValue_h -#define JSValue_h - -#include <math.h> -#include <stddef.h> // for size_t -#include <stdint.h> -#include <wtf/AlwaysInline.h> -#include <wtf/Assertions.h> -#include <wtf/HashTraits.h> -#include <wtf/MathExtras.h> - -namespace JSC { - - class ExecState; - class Identifier; - class JSCell; - class JSGlobalData; - class JSImmediate; - class JSObject; - class JSString; - class PropertySlot; - class PutPropertySlot; - class UString; - - struct ClassInfo; - struct Instruction; - - enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString }; - -#if USE(JSVALUE32_64) - typedef int64_t EncodedJSValue; -#else - typedef void* EncodedJSValue; -#endif - - double nonInlineNaN(); - - // This implements ToInt32, defined in ECMA-262 9.5. - int32_t toInt32(double); - - // This implements ToUInt32, defined in ECMA-262 9.6. - inline uint32_t toUInt32(double number) - { - // As commented in the spec, the operation of ToInt32 and ToUint32 only differ - // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6. - return toInt32(number); - } - - class JSValue { - friend class JSImmediate; - friend struct EncodedJSValueHashTraits; - friend class JIT; - friend class JITStubs; - friend class JITStubCall; - friend class JSInterfaceJIT; - friend class SpecializedThunkJIT; - - public: - static EncodedJSValue encode(JSValue value); - static JSValue decode(EncodedJSValue ptr); -#if USE(JSVALUE64) - private: - static JSValue makeImmediate(intptr_t value); - intptr_t immediateValue(); - public: -#endif - enum JSNullTag { JSNull }; - enum JSUndefinedTag { JSUndefined }; - enum JSTrueTag { JSTrue }; - enum JSFalseTag { JSFalse }; - enum EncodeAsDoubleTag { EncodeAsDouble }; - - JSValue(); - JSValue(JSNullTag); - JSValue(JSUndefinedTag); - JSValue(JSTrueTag); - JSValue(JSFalseTag); - JSValue(JSCell* ptr); - JSValue(const JSCell* ptr); - - // Numbers - JSValue(EncodeAsDoubleTag, double); - explicit JSValue(double); - explicit JSValue(char); - explicit JSValue(unsigned char); - explicit JSValue(short); - explicit JSValue(unsigned short); - explicit JSValue(int); - explicit JSValue(unsigned); - explicit JSValue(long); - explicit JSValue(unsigned long); - explicit JSValue(long long); - explicit JSValue(unsigned long long); - - operator bool() const; - bool operator==(const JSValue& other) const; - bool operator!=(const JSValue& other) const; - - bool isInt32() const; - bool isUInt32() const; - bool isDouble() const; - bool isTrue() const; - bool isFalse() const; - - int32_t asInt32() const; - uint32_t asUInt32() const; - double asDouble() const; - - // Querying the type. - bool isUndefined() const; - bool isNull() const; - bool isUndefinedOrNull() const; - bool isBoolean() const; - bool isNumber() const; - bool isString() const; - bool isGetterSetter() const; - bool isObject() const; - bool inherits(const ClassInfo*) const; - - // Extracting the value. - bool getBoolean(bool&) const; - bool getBoolean() const; // false if not a boolean - bool getNumber(double&) const; - double uncheckedGetNumber() const; - bool getString(ExecState* exec, UString&) const; - UString getString(ExecState* exec) const; // null string if not a string - JSObject* getObject() const; // 0 if not an object - - // Extracting integer values. - bool getUInt32(uint32_t&) const; - - // Basic conversions. - JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; - bool getPrimitiveNumber(ExecState*, double& number, JSValue&); - - bool toBoolean(ExecState*) const; - - // toNumber conversion is expected to be side effect free if an exception has - // been set in the ExecState already. - double toNumber(ExecState*) const; - JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number. - UString toString(ExecState*) const; - UString toPrimitiveString(ExecState*) const; - JSObject* toObject(ExecState*) const; - - // Integer conversions. - double toInteger(ExecState*) const; - double toIntegerPreserveNaN(ExecState*) const; - int32_t toInt32(ExecState*) const; - uint32_t toUInt32(ExecState*) const; - -#if ENABLE(JSC_ZOMBIES) - bool isZombie() const; -#endif - - // 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)); } - - // Object operations, with the toObject operation included. - JSValue get(ExecState*, const Identifier& propertyName) const; - JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const; - JSValue get(ExecState*, unsigned propertyName) const; - JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const; - void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - void put(ExecState*, unsigned propertyName, JSValue); - - bool needsThisConversion() const; - JSObject* toThisObject(ExecState*) const; - JSValue toStrictThisObject(ExecState*) const; - UString toThisString(ExecState*) const; - JSString* toThisJSString(ExecState*) const; - - 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(ExecState* exec, JSValue v1, JSValue v2); - static bool strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2); - static bool strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2); - - JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object - - bool isCell() const; - JSCell* asCell() const; - bool isValidCallee(); - -#ifndef NDEBUG - char* description(); -#endif - - private: - enum HashTableDeletedValueTag { HashTableDeletedValue }; - JSValue(HashTableDeletedValueTag); - - inline const JSValue asValue() const { return *this; } - JSObject* toObjectSlowCase(ExecState*) const; - JSObject* toThisObjectSlowCase(ExecState*) const; - - JSObject* synthesizePrototype(ExecState*) const; - JSObject* synthesizeObject(ExecState*) const; - -#if USE(JSVALUE32_64) - enum { NullTag = 0xffffffff }; - enum { UndefinedTag = 0xfffffffe }; - enum { Int32Tag = 0xfffffffd }; - enum { CellTag = 0xfffffffc }; - enum { TrueTag = 0xfffffffb }; - enum { FalseTag = 0xfffffffa }; - enum { EmptyValueTag = 0xfffffff9 }; - enum { DeletedValueTag = 0xfffffff8 }; - - enum { LowestTag = DeletedValueTag }; - - uint32_t tag() const; - int32_t payload() const; - - union { - EncodedJSValue asEncodedJSValue; - double asDouble; -#if CPU(BIG_ENDIAN) - struct { - int32_t tag; - int32_t payload; - } asBits; -#else - struct { - int32_t payload; - int32_t tag; - } asBits; -#endif - } u; -#else // USE(JSVALUE32_64) - JSCell* m_ptr; -#endif // USE(JSVALUE32_64) - }; - -#if USE(JSVALUE32_64) - typedef IntHash<EncodedJSValue> EncodedJSValueHash; - - struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> { - static const bool emptyValueIsZero = false; - static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); } - static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } - static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); } - }; -#else - typedef PtrHash<EncodedJSValue> EncodedJSValueHash; - - struct EncodedJSValueHashTraits : 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)); } - }; -#endif - - // Stand-alone helper functions. - inline JSValue jsNull() - { - return JSValue(JSValue::JSNull); - } - - inline JSValue jsUndefined() - { - return JSValue(JSValue::JSUndefined); - } - - inline JSValue jsBoolean(bool b) - { - return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse); - } - - ALWAYS_INLINE JSValue jsDoubleNumber(double d) - { - return JSValue(JSValue::EncodeAsDouble, d); - } - - ALWAYS_INLINE JSValue jsNumber(double d) - { - return JSValue(d); - } - - ALWAYS_INLINE JSValue jsNumber(char i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(unsigned char i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(short i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(unsigned short i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(int i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(unsigned i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(long i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(unsigned long i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(long long i) - { - return JSValue(i); - } - - ALWAYS_INLINE JSValue jsNumber(unsigned long long i) - { - return JSValue(i); - } - - inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); } - inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; } - - inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); } - inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; } - - ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const - { - if (isInt32()) - return asInt32(); - return JSC::toInt32(toNumber(exec)); - } - - inline uint32_t JSValue::toUInt32(ExecState* exec) const - { - // See comment on JSC::toUInt32, above. - return toInt32(exec); - } - -#if USE(JSVALUE32_64) - inline JSValue jsNaN() - { - return JSValue(nonInlineNaN()); - } - - // JSValue member functions. - inline EncodedJSValue JSValue::encode(JSValue value) - { - return value.u.asEncodedJSValue; - } - - inline JSValue JSValue::decode(EncodedJSValue encodedJSValue) - { - JSValue v; - v.u.asEncodedJSValue = encodedJSValue; -#if ENABLE(JSC_ZOMBIES) - ASSERT(!v.isZombie()); -#endif - return v; - } - - inline JSValue::JSValue() - { - u.asBits.tag = EmptyValueTag; - u.asBits.payload = 0; - } - - inline JSValue::JSValue(JSNullTag) - { - u.asBits.tag = NullTag; - u.asBits.payload = 0; - } - - inline JSValue::JSValue(JSUndefinedTag) - { - u.asBits.tag = UndefinedTag; - u.asBits.payload = 0; - } - - inline JSValue::JSValue(JSTrueTag) - { - u.asBits.tag = TrueTag; - u.asBits.payload = 0; - } - - inline JSValue::JSValue(JSFalseTag) - { - u.asBits.tag = FalseTag; - u.asBits.payload = 0; - } - - inline JSValue::JSValue(HashTableDeletedValueTag) - { - u.asBits.tag = DeletedValueTag; - u.asBits.payload = 0; - } - - inline JSValue::JSValue(JSCell* ptr) - { - if (ptr) - u.asBits.tag = CellTag; - else - u.asBits.tag = EmptyValueTag; - u.asBits.payload = reinterpret_cast<int32_t>(ptr); -#if ENABLE(JSC_ZOMBIES) - ASSERT(!isZombie()); -#endif - } - - inline JSValue::JSValue(const JSCell* ptr) - { - if (ptr) - u.asBits.tag = CellTag; - else - u.asBits.tag = EmptyValueTag; - u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr)); -#if ENABLE(JSC_ZOMBIES) - ASSERT(!isZombie()); -#endif - } - - inline JSValue::operator bool() const - { - ASSERT(tag() != DeletedValueTag); - return tag() != EmptyValueTag; - } - - inline bool JSValue::operator==(const JSValue& other) const - { - return u.asEncodedJSValue == other.u.asEncodedJSValue; - } - - inline bool JSValue::operator!=(const JSValue& other) const - { - return u.asEncodedJSValue != other.u.asEncodedJSValue; - } - - inline bool JSValue::isUndefined() const - { - return tag() == UndefinedTag; - } - - inline bool JSValue::isNull() const - { - return tag() == NullTag; - } - - inline bool JSValue::isUndefinedOrNull() const - { - return isUndefined() || isNull(); - } - - inline bool JSValue::isCell() const - { - return tag() == CellTag; - } - - inline bool JSValue::isInt32() const - { - return tag() == Int32Tag; - } - - inline bool JSValue::isUInt32() const - { - return tag() == Int32Tag && asInt32() > -1; - } - - inline bool JSValue::isDouble() const - { - return tag() < LowestTag; - } - - inline bool JSValue::isTrue() const - { - return tag() == TrueTag; - } - - inline bool JSValue::isFalse() const - { - return tag() == FalseTag; - } - - inline uint32_t JSValue::tag() const - { - return u.asBits.tag; - } - - inline int32_t JSValue::payload() const - { - return u.asBits.payload; - } - - inline int32_t JSValue::asInt32() const - { - ASSERT(isInt32()); - return u.asBits.payload; - } - - inline uint32_t JSValue::asUInt32() const - { - ASSERT(isUInt32()); - return u.asBits.payload; - } - - inline double JSValue::asDouble() const - { - ASSERT(isDouble()); - return u.asDouble; - } - - ALWAYS_INLINE JSCell* JSValue::asCell() const - { - ASSERT(isCell()); - return reinterpret_cast<JSCell*>(u.asBits.payload); - } - - ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d) - { - u.asDouble = d; - } - - inline JSValue::JSValue(double d) - { - const int32_t asInt32 = static_cast<int32_t>(d); - if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0 - u.asDouble = d; - return; - } - *this = JSValue(static_cast<int32_t>(d)); - } - - inline JSValue::JSValue(char i) - { - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(unsigned char i) - { - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(short i) - { - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(unsigned short i) - { - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(int i) - { - u.asBits.tag = Int32Tag; - u.asBits.payload = i; - } - - inline JSValue::JSValue(unsigned i) - { - if (static_cast<int32_t>(i) < 0) { - *this = JSValue(static_cast<double>(i)); - return; - } - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(long i) - { - if (static_cast<int32_t>(i) != i) { - *this = JSValue(static_cast<double>(i)); - return; - } - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(unsigned long i) - { - if (static_cast<uint32_t>(i) != i) { - *this = JSValue(static_cast<double>(i)); - return; - } - *this = JSValue(static_cast<uint32_t>(i)); - } - - inline JSValue::JSValue(long long i) - { - if (static_cast<int32_t>(i) != i) { - *this = JSValue(static_cast<double>(i)); - return; - } - *this = JSValue(static_cast<int32_t>(i)); - } - - inline JSValue::JSValue(unsigned long long i) - { - if (static_cast<uint32_t>(i) != i) { - *this = JSValue(static_cast<double>(i)); - return; - } - *this = JSValue(static_cast<uint32_t>(i)); - } - - inline bool JSValue::isNumber() const - { - return isInt32() || isDouble(); - } - - inline bool JSValue::isBoolean() const - { - return isTrue() || isFalse(); - } - - inline bool JSValue::getBoolean(bool& v) const - { - if (isTrue()) { - v = true; - return true; - } - if (isFalse()) { - v = false; - return true; - } - - return false; - } - - inline bool JSValue::getBoolean() const - { - ASSERT(isBoolean()); - return tag() == TrueTag; - } - - inline double JSValue::uncheckedGetNumber() const - { - ASSERT(isNumber()); - return isInt32() ? asInt32() : asDouble(); - } - - ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const - { - return isNumber() ? asValue() : jsNumber(this->toNumber(exec)); - } - - inline bool JSValue::getNumber(double& result) const - { - if (isInt32()) { - result = asInt32(); - return true; - } - if (isDouble()) { - result = asDouble(); - return true; - } - return false; - } - -#else // USE(JSVALUE32_64) - - // 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)); - } - - inline JSValue JSValue::makeImmediate(intptr_t value) - { - return JSValue(reinterpret_cast<JSCell*>(value)); - } - - inline intptr_t JSValue::immediateValue() - { - return reinterpret_cast<intptr_t>(m_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) - { -#if ENABLE(JSC_ZOMBIES) - ASSERT(!isZombie()); -#endif - } - - inline JSValue::JSValue(const JSCell* ptr) - : m_ptr(const_cast<JSCell*>(ptr)) - { -#if ENABLE(JSC_ZOMBIES) - ASSERT(!isZombie()); -#endif - } - - 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(); - } -#endif // USE(JSVALUE32_64) - - typedef std::pair<JSValue, UString> ValueStringPair; -} // namespace JSC - -#endif // JSValue_h diff --git a/JavaScriptCore/runtime/JSVariableObject.cpp b/JavaScriptCore/runtime/JSVariableObject.cpp deleted file mode 100644 index 81d05ba..0000000 --- a/JavaScriptCore/runtime/JSVariableObject.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "JSVariableObject.h" - -#include "PropertyNameArray.h" -#include "PropertyDescriptor.h" - -namespace JSC { - -bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - if (symbolTable().contains(propertyName.impl())) - return false; - - return JSObject::deleteProperty(exec, propertyName); -} - -void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - SymbolTable::const_iterator end = symbolTable().end(); - for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) { - if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties)) - propertyNames.add(Identifier(exec, it->first.get())); - } - - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -bool JSVariableObject::isVariableObject() const -{ - return true; -} - -bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); - if (!entry.isNull()) { - descriptor.setDescriptor(registerAt(entry.getIndex()).jsValue(), entry.getAttributes() | DontDelete); - return true; - } - return false; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSVariableObject.h b/JavaScriptCore/runtime/JSVariableObject.h deleted file mode 100644 index 3f2e218..0000000 --- a/JavaScriptCore/runtime/JSVariableObject.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSVariableObject_h -#define JSVariableObject_h - -#include "JSObject.h" -#include "Register.h" -#include "SymbolTable.h" -#include "UnusedParam.h" -#include <wtf/OwnArrayPtr.h> -#include <wtf/UnusedParam.h> - -namespace JSC { - - class Register; - - class JSVariableObject : public JSObject { - friend class JIT; - - public: - SymbolTable& symbolTable() const { return *d->symbolTable; } - - virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0; - - virtual bool deleteProperty(ExecState*, const Identifier&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - - virtual bool isVariableObject() const; - virtual bool isDynamicScope(bool& requiresDynamicChecks) const = 0; - - Register& registerAt(int index) const { return d->registers[index]; } - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags; - // Subclasses of JSVariableObject can subclass this struct to add data - // without increasing their own size (since there's a hard limit on the - // size of a JSCell). - struct JSVariableObjectData { - JSVariableObjectData(SymbolTable* symbolTable, Register* registers) - : symbolTable(symbolTable) - , registers(registers) - { - ASSERT(symbolTable); - } - - SymbolTable* symbolTable; // Maps name -> offset from "r" in register file. - Register* registers; // "r" in the register file. - OwnArrayPtr<Register> registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file. - - private: - JSVariableObjectData(const JSVariableObjectData&); - JSVariableObjectData& operator=(const JSVariableObjectData&); - }; - - JSVariableObject(NonNullPassRefPtr<Structure> structure, JSVariableObjectData* data) - : JSObject(structure) - , d(data) // Subclass owns this pointer. - { - } - - Register* copyRegisterArray(Register* src, size_t count); - void setRegisters(Register* r, Register* registerArray); - - bool symbolTableGet(const Identifier&, PropertySlot&); - bool symbolTableGet(const Identifier&, PropertyDescriptor&); - bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); - bool symbolTablePut(const Identifier&, JSValue); - bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes); - - JSVariableObjectData* d; - }; - - inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot) - { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); - if (!entry.isNull()) { - slot.setRegisterSlot(®isterAt(entry.getIndex())); - return true; - } - return false; - } - - inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable) - { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); - if (!entry.isNull()) { - slot.setRegisterSlot(®isterAt(entry.getIndex())); - slotIsWriteable = !entry.isReadOnly(); - return true; - } - return false; - } - - inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue value) - { - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); - if (entry.isNull()) - return false; - if (entry.isReadOnly()) - return true; - registerAt(entry.getIndex()) = value; - return true; - } - - inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes) - { - ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - - SymbolTable::iterator iter = symbolTable().find(propertyName.impl()); - if (iter == symbolTable().end()) - return false; - SymbolTableEntry& entry = iter->second; - ASSERT(!entry.isNull()); - entry.setAttributes(attributes); - registerAt(entry.getIndex()) = value; - return true; - } - - inline Register* JSVariableObject::copyRegisterArray(Register* src, size_t count) - { - Register* registerArray = new Register[count]; - memcpy(registerArray, src, count * sizeof(Register)); - - return registerArray; - } - - inline void JSVariableObject::setRegisters(Register* registers, Register* registerArray) - { - ASSERT(registerArray != d->registerArray.get()); - d->registerArray.set(registerArray); - d->registers = registers; - } - -} // namespace JSC - -#endif // JSVariableObject_h diff --git a/JavaScriptCore/runtime/JSWrapperObject.cpp b/JavaScriptCore/runtime/JSWrapperObject.cpp deleted file mode 100644 index 2c39f5c..0000000 --- a/JavaScriptCore/runtime/JSWrapperObject.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2006 Maks Orlovich - * Copyright (C) 2006, 2009 Apple, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "JSWrapperObject.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject); - -void JSWrapperObject::markChildren(MarkStack& markStack) -{ - JSObject::markChildren(markStack); - if (m_internalValue) - markStack.append(m_internalValue); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/JSWrapperObject.h b/JavaScriptCore/runtime/JSWrapperObject.h deleted file mode 100644 index f19cd30..0000000 --- a/JavaScriptCore/runtime/JSWrapperObject.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2006 Maks Orlovich - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSWrapperObject_h -#define JSWrapperObject_h - -#include "JSObject.h" - -namespace JSC { - - // This class is used as a base for classes such as String, - // Number, Boolean and Date which are wrappers for primitive types. - class JSWrapperObject : public JSObject { - protected: - explicit JSWrapperObject(NonNullPassRefPtr<Structure>); - - public: - JSValue internalValue() const { return m_internalValue; } - void setInternalValue(JSValue); - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned AnonymousSlotCount = 1 + JSObject::AnonymousSlotCount; - - private: - virtual void markChildren(MarkStack&); - - JSValue m_internalValue; - }; - - inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure) - : JSObject(structure) - { - putAnonymousValue(0, jsNull()); - } - - inline void JSWrapperObject::setInternalValue(JSValue value) - { - ASSERT(value); - ASSERT(!value.isObject()); - m_internalValue = value; - putAnonymousValue(0, value); - } - -} // namespace JSC - -#endif // JSWrapperObject_h diff --git a/JavaScriptCore/runtime/JSZombie.cpp b/JavaScriptCore/runtime/JSZombie.cpp deleted file mode 100644 index 8a36bda..0000000 --- a/JavaScriptCore/runtime/JSZombie.cpp +++ /dev/null @@ -1,48 +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. - */ - -#include "config.h" -#include "JSZombie.h" -#include "ClassInfo.h" - -#if ENABLE(JSC_ZOMBIES) - -namespace JSC { - -const ClassInfo JSZombie::s_info = { "Zombie", 0, 0, 0 }; - -Structure* JSZombie::leakedZombieStructure() { - static Structure* structure = 0; - if (!structure) { - Structure::startIgnoringLeaks(); - structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType), 0).leakRef(); - Structure::stopIgnoringLeaks(); - } - return structure; -} - -} - -#endif // ENABLE(JSC_ZOMBIES) diff --git a/JavaScriptCore/runtime/JSZombie.h b/JavaScriptCore/runtime/JSZombie.h deleted file mode 100644 index da45699..0000000 --- a/JavaScriptCore/runtime/JSZombie.h +++ /dev/null @@ -1,77 +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 JSZombie_h -#define JSZombie_h - -#include "JSCell.h" - -#if ENABLE(JSC_ZOMBIES) -namespace JSC { - -class JSZombie : public JSCell { -public: - JSZombie(const ClassInfo* oldInfo, Structure* structure) - : JSCell(structure) - , m_oldInfo(oldInfo) - { - } - virtual bool isZombie() const { return true; } - virtual const ClassInfo* classInfo() const { return &s_info; } - static Structure* leakedZombieStructure(); - - virtual bool isGetterSetter() const { ASSERT_NOT_REACHED(); return false; } - virtual bool isAPIValueWrapper() const { ASSERT_NOT_REACHED(); return false; } - virtual bool isPropertyNameIterator() const { ASSERT_NOT_REACHED(); return false; } - virtual CallType getCallData(CallData&) { ASSERT_NOT_REACHED(); return CallTypeNone; } - virtual ConstructType getConstructData(ConstructData&) { ASSERT_NOT_REACHED(); return ConstructTypeNone; } - virtual bool getUInt32(uint32_t&) const { ASSERT_NOT_REACHED(); return false; } - virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const { ASSERT_NOT_REACHED(); return jsNull(); } - virtual bool getPrimitiveNumber(ExecState*, double&, JSValue&) { ASSERT_NOT_REACHED(); return false; } - virtual bool toBoolean(ExecState*) const { ASSERT_NOT_REACHED(); return false; } - virtual double toNumber(ExecState*) const { ASSERT_NOT_REACHED(); return 0.0; } - virtual UString toString(ExecState*) const { ASSERT_NOT_REACHED(); return ""; } - virtual JSObject* toObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; } - virtual void markChildren(MarkStack&) { ASSERT_NOT_REACHED(); } - virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&) { ASSERT_NOT_REACHED(); } - virtual void put(ExecState*, unsigned, JSValue) { ASSERT_NOT_REACHED(); } - virtual bool deleteProperty(ExecState*, const Identifier&) { ASSERT_NOT_REACHED(); return false; } - virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; } - virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; } - virtual JSValue toStrictThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return JSValue(); } - virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); } - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; } - virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; } - - static const ClassInfo s_info; -private: - const ClassInfo* m_oldInfo; -}; - -} - -#endif // ENABLE(JSC_ZOMBIES) - -#endif // JSZombie_h diff --git a/JavaScriptCore/runtime/LiteralParser.cpp b/JavaScriptCore/runtime/LiteralParser.cpp deleted file mode 100644 index ed69f4d..0000000 --- a/JavaScriptCore/runtime/LiteralParser.cpp +++ /dev/null @@ -1,455 +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. - */ - -#include "config.h" -#include "LiteralParser.h" - -#include "JSArray.h" -#include "JSString.h" -#include "Lexer.h" -#include "UStringBuilder.h" -#include <wtf/ASCIICType.h> -#include <wtf/dtoa.h> - -namespace JSC { - -LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token) -{ - while (m_ptr < m_end && isASCIISpace(*m_ptr)) - ++m_ptr; - - ASSERT(m_ptr <= m_end); - if (m_ptr >= m_end) { - token.type = TokEnd; - token.start = token.end = m_ptr; - return TokEnd; - } - token.type = TokError; - token.start = m_ptr; - switch (*m_ptr) { - case '[': - token.type = TokLBracket; - token.end = ++m_ptr; - return TokLBracket; - case ']': - token.type = TokRBracket; - token.end = ++m_ptr; - return TokRBracket; - case '(': - token.type = TokLParen; - token.end = ++m_ptr; - return TokLBracket; - case ')': - token.type = TokRParen; - token.end = ++m_ptr; - return TokRBracket; - case '{': - token.type = TokLBrace; - token.end = ++m_ptr; - return TokLBrace; - case '}': - token.type = TokRBrace; - token.end = ++m_ptr; - return TokRBrace; - case ',': - token.type = TokComma; - token.end = ++m_ptr; - return TokComma; - case ':': - token.type = TokColon; - token.end = ++m_ptr; - return TokColon; - case '"': - if (m_mode == StrictJSON) - return lexString<StrictJSON>(token); - return lexString<NonStrictJSON>(token); - case 't': - if (m_end - m_ptr >= 4 && m_ptr[1] == 'r' && m_ptr[2] == 'u' && m_ptr[3] == 'e') { - m_ptr += 4; - token.type = TokTrue; - token.end = m_ptr; - return TokTrue; - } - break; - case 'f': - if (m_end - m_ptr >= 5 && m_ptr[1] == 'a' && m_ptr[2] == 'l' && m_ptr[3] == 's' && m_ptr[4] == 'e') { - m_ptr += 5; - token.type = TokFalse; - token.end = m_ptr; - return TokFalse; - } - break; - case 'n': - if (m_end - m_ptr >= 4 && m_ptr[1] == 'u' && m_ptr[2] == 'l' && m_ptr[3] == 'l') { - m_ptr += 4; - token.type = TokNull; - token.end = m_ptr; - return TokNull; - } - break; - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return lexNumber(token); - } - return TokError; -} - -template <LiteralParser::ParserMode mode> static inline bool isSafeStringCharacter(UChar c) -{ - return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != '"') || c == '\t'; -} - -// "inline" is required here to help WINSCW compiler resolve specialized argument in templated functions. -template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) -{ - ++m_ptr; - const UChar* runStart; - UStringBuilder builder; - do { - runStart = m_ptr; - while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr)) - ++m_ptr; - if (runStart < m_ptr) - builder.append(runStart, m_ptr - runStart); - if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') { - ++m_ptr; - if (m_ptr >= m_end) - return TokError; - switch (*m_ptr) { - case '"': - builder.append('"'); - m_ptr++; - break; - case '\\': - builder.append('\\'); - m_ptr++; - break; - case '/': - builder.append('/'); - m_ptr++; - break; - case 'b': - builder.append('\b'); - m_ptr++; - break; - case 'f': - builder.append('\f'); - m_ptr++; - break; - case 'n': - builder.append('\n'); - m_ptr++; - break; - case 'r': - builder.append('\r'); - m_ptr++; - break; - case 't': - builder.append('\t'); - m_ptr++; - break; - - case 'u': - if ((m_end - m_ptr) < 5) // uNNNN == 5 characters - return TokError; - for (int i = 1; i < 5; i++) { - if (!isASCIIHexDigit(m_ptr[i])) - return TokError; - } - builder.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4])); - m_ptr += 5; - break; - - default: - return TokError; - } - } - } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"'); - - if (m_ptr >= m_end || *m_ptr != '"') - return TokError; - - token.stringToken = builder.toUString(); - token.type = TokString; - token.end = ++m_ptr; - return TokString; -} - -LiteralParser::TokenType LiteralParser::Lexer::lexNumber(LiteralParserToken& token) -{ - // ES5 and json.org define numbers as - // number - // int - // int frac? exp? - // - // int - // -? 0 - // -? digit1-9 digits? - // - // digits - // digit digits? - // - // -?(0 | [1-9][0-9]*) ('.' [0-9]+)? ([eE][+-]? [0-9]+)? - - if (m_ptr < m_end && *m_ptr == '-') // -? - ++m_ptr; - - // (0 | [1-9][0-9]*) - if (m_ptr < m_end && *m_ptr == '0') // 0 - ++m_ptr; - else if (m_ptr < m_end && *m_ptr >= '1' && *m_ptr <= '9') { // [1-9] - ++m_ptr; - // [0-9]* - while (m_ptr < m_end && isASCIIDigit(*m_ptr)) - ++m_ptr; - } else - return TokError; - - // ('.' [0-9]+)? - if (m_ptr < m_end && *m_ptr == '.') { - ++m_ptr; - // [0-9]+ - if (m_ptr >= m_end || !isASCIIDigit(*m_ptr)) - return TokError; - - ++m_ptr; - while (m_ptr < m_end && isASCIIDigit(*m_ptr)) - ++m_ptr; - } - - // ([eE][+-]? [0-9]+)? - if (m_ptr < m_end && (*m_ptr == 'e' || *m_ptr == 'E')) { // [eE] - ++m_ptr; - - // [-+]? - if (m_ptr < m_end && (*m_ptr == '-' || *m_ptr == '+')) - ++m_ptr; - - // [0-9]+ - if (m_ptr >= m_end || !isASCIIDigit(*m_ptr)) - return TokError; - - ++m_ptr; - while (m_ptr < m_end && isASCIIDigit(*m_ptr)) - ++m_ptr; - } - - token.type = TokNumber; - token.end = m_ptr; - Vector<char, 64> buffer(token.end - token.start + 1); - int i; - for (i = 0; i < token.end - token.start; i++) { - ASSERT(static_cast<char>(token.start[i]) == token.start[i]); - buffer[i] = static_cast<char>(token.start[i]); - } - buffer[i] = 0; - char* end; - token.numberToken = WTF::strtod(buffer.data(), &end); - ASSERT(buffer.data() + (token.end - token.start) == end); - return TokNumber; -} - -JSValue LiteralParser::parse(ParserState initialState) -{ - ParserState state = initialState; - MarkedArgumentBuffer objectStack; - JSValue lastValue; - Vector<ParserState, 16> stateStack; - Vector<Identifier, 16> identifierStack; - while (1) { - switch(state) { - startParseArray: - case StartParseArray: { - JSArray* array = constructEmptyArray(m_exec); - objectStack.append(array); - // fallthrough - } - doParseArrayStartExpression: - case DoParseArrayStartExpression: { - TokenType lastToken = m_lexer.currentToken().type; - if (m_lexer.next() == TokRBracket) { - if (lastToken == TokComma) - return JSValue(); - m_lexer.next(); - lastValue = objectStack.last(); - objectStack.removeLast(); - break; - } - - stateStack.append(DoParseArrayEndExpression); - goto startParseExpression; - } - case DoParseArrayEndExpression: { - asArray(objectStack.last())->push(m_exec, lastValue); - - if (m_lexer.currentToken().type == TokComma) - goto doParseArrayStartExpression; - - if (m_lexer.currentToken().type != TokRBracket) - return JSValue(); - - m_lexer.next(); - lastValue = objectStack.last(); - objectStack.removeLast(); - break; - } - startParseObject: - case StartParseObject: { - JSObject* object = constructEmptyObject(m_exec); - objectStack.append(object); - - TokenType type = m_lexer.next(); - if (type == TokString) { - Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); - - // Check for colon - if (m_lexer.next() != TokColon) - return JSValue(); - - m_lexer.next(); - identifierStack.append(Identifier(m_exec, identifierToken.stringToken)); - stateStack.append(DoParseObjectEndExpression); - goto startParseExpression; - } else if (type != TokRBrace) - return JSValue(); - m_lexer.next(); - lastValue = objectStack.last(); - objectStack.removeLast(); - break; - } - doParseObjectStartExpression: - case DoParseObjectStartExpression: { - TokenType type = m_lexer.next(); - if (type != TokString) - return JSValue(); - Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); - - // Check for colon - if (m_lexer.next() != TokColon) - return JSValue(); - - m_lexer.next(); - identifierStack.append(Identifier(m_exec, identifierToken.stringToken)); - stateStack.append(DoParseObjectEndExpression); - goto startParseExpression; - } - case DoParseObjectEndExpression: - { - asObject(objectStack.last())->putDirect(identifierStack.last(), lastValue); - identifierStack.removeLast(); - if (m_lexer.currentToken().type == TokComma) - goto doParseObjectStartExpression; - if (m_lexer.currentToken().type != TokRBrace) - return JSValue(); - m_lexer.next(); - lastValue = objectStack.last(); - objectStack.removeLast(); - break; - } - startParseExpression: - case StartParseExpression: { - switch (m_lexer.currentToken().type) { - case TokLBracket: - goto startParseArray; - case TokLBrace: - goto startParseObject; - case TokString: { - Lexer::LiteralParserToken stringToken = m_lexer.currentToken(); - m_lexer.next(); - lastValue = jsString(m_exec, stringToken.stringToken); - break; - } - case TokNumber: { - Lexer::LiteralParserToken numberToken = m_lexer.currentToken(); - m_lexer.next(); - lastValue = jsNumber(numberToken.numberToken); - break; - } - case TokNull: - m_lexer.next(); - lastValue = jsNull(); - break; - - case TokTrue: - m_lexer.next(); - lastValue = jsBoolean(true); - break; - - case TokFalse: - m_lexer.next(); - lastValue = jsBoolean(false); - break; - - default: - // Error - return JSValue(); - } - break; - } - case StartParseStatement: { - switch (m_lexer.currentToken().type) { - case TokLBracket: - case TokNumber: - case TokString: - goto startParseExpression; - - case TokLParen: { - m_lexer.next(); - stateStack.append(StartParseStatementEndStatement); - goto startParseExpression; - } - default: - return JSValue(); - } - } - case StartParseStatementEndStatement: { - ASSERT(stateStack.isEmpty()); - if (m_lexer.currentToken().type != TokRParen) - return JSValue(); - if (m_lexer.next() == TokEnd) - return lastValue; - return JSValue(); - } - default: - ASSERT_NOT_REACHED(); - } - if (stateStack.isEmpty()) - return lastValue; - state = stateStack.last(); - stateStack.removeLast(); - continue; - } -} - -} diff --git a/JavaScriptCore/runtime/LiteralParser.h b/JavaScriptCore/runtime/LiteralParser.h deleted file mode 100644 index 6df5d06..0000000 --- a/JavaScriptCore/runtime/LiteralParser.h +++ /dev/null @@ -1,110 +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 LiteralParser_h -#define LiteralParser_h - -#include "JSGlobalObjectFunctions.h" -#include "JSValue.h" -#include "UString.h" - -namespace JSC { - - class LiteralParser { - public: - typedef enum { StrictJSON, NonStrictJSON } ParserMode; - LiteralParser(ExecState* exec, const UString& s, ParserMode mode) - : m_exec(exec) - , m_lexer(s, mode) - , m_mode(mode) - { - } - - JSValue tryLiteralParse() - { - m_lexer.next(); - JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement); - if (m_lexer.currentToken().type != TokEnd) - return JSValue(); - return result; - } - private: - enum ParserState { StartParseObject, StartParseArray, StartParseExpression, - StartParseStatement, StartParseStatementEndStatement, - DoParseObjectStartExpression, DoParseObjectEndExpression, - DoParseArrayStartExpression, DoParseArrayEndExpression }; - enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace, - TokString, TokIdentifier, TokNumber, TokColon, - TokLParen, TokRParen, TokComma, TokTrue, TokFalse, - TokNull, TokEnd, TokError }; - - class Lexer { - public: - struct LiteralParserToken { - TokenType type; - const UChar* start; - const UChar* end; - UString stringToken; - double numberToken; - }; - Lexer(const UString& s, ParserMode mode) - : m_string(s) - , m_mode(mode) - , m_ptr(s.characters()) - , m_end(s.characters() + s.length()) - { - } - - TokenType next() - { - return lex(m_currentToken); - } - - const LiteralParserToken& currentToken() - { - return m_currentToken; - } - - private: - TokenType lex(LiteralParserToken&); - template <ParserMode mode> TokenType lexString(LiteralParserToken&); - TokenType lexNumber(LiteralParserToken&); - LiteralParserToken m_currentToken; - UString m_string; - ParserMode m_mode; - const UChar* m_ptr; - const UChar* m_end; - }; - - class StackGuard; - JSValue parse(ParserState); - - ExecState* m_exec; - LiteralParser::Lexer m_lexer; - ParserMode m_mode; - }; -} - -#endif diff --git a/JavaScriptCore/runtime/Lookup.cpp b/JavaScriptCore/runtime/Lookup.cpp deleted file mode 100644 index dac1c94..0000000 --- a/JavaScriptCore/runtime/Lookup.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "Lookup.h" - -#include "Executable.h" -#include "JSFunction.h" -#include "PrototypeFunction.h" - -namespace JSC { - -void HashTable::createTable(JSGlobalData* globalData) const -{ - ASSERT(!table); - int linkIndex = compactHashSizeMask + 1; - HashEntry* entries = new HashEntry[compactSize]; - for (int i = 0; i < compactSize; ++i) - entries[i].setKey(0); - for (int i = 0; values[i].key; ++i) { - StringImpl* identifier = Identifier::add(globalData, values[i].key).leakRef(); - int hashIndex = identifier->existingHash() & compactHashSizeMask; - HashEntry* entry = &entries[hashIndex]; - - if (entry->key()) { - while (entry->next()) { - entry = entry->next(); - } - ASSERT(linkIndex < compactSize); - entry->setNext(&entries[linkIndex++]); - entry = entry->next(); - } - - entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2 -#if ENABLE(JIT) - , values[i].generator -#endif - ); - } - table = entries; -} - -void HashTable::deleteTable() const -{ - if (table) { - int max = compactSize; - for (int i = 0; i != max; ++i) { - if (StringImpl* key = table[i].key()) - key->deref(); - } - delete [] table; - table = 0; - } -} - -void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot) -{ - ASSERT(thisObj->structure()->anonymousSlotCount() > 0); - ASSERT(thisObj->getAnonymousValue(0).isCell() && asObject(thisObj->getAnonymousValue(0).asCell())->isGlobalObject()); - ASSERT(entry->attributes() & Function); - JSValue* location = thisObj->getDirectLocation(propertyName); - - if (!location) { - NativeFunctionWrapper* function; - JSGlobalObject* globalObject = asGlobalObject(thisObj->getAnonymousValue(0).asCell()); -#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL) - if (entry->generator()) - function = new (exec) NativeFunctionWrapper(exec, globalObject, globalObject->prototypeFunctionStructure(), entry->functionLength(), propertyName, exec->globalData().getHostFunction(entry->function(), entry->generator())); - else -#endif - function = new (exec) NativeFunctionWrapper(exec, globalObject, globalObject->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function()); - - thisObj->putDirectFunction(propertyName, function, entry->attributes()); - location = thisObj->getDirectLocation(propertyName); - } - - slot.setValueSlot(thisObj, location, thisObj->offsetForLocation(location)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Lookup.h b/JavaScriptCore/runtime/Lookup.h deleted file mode 100644 index 9bc81d4..0000000 --- a/JavaScriptCore/runtime/Lookup.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef Lookup_h -#define Lookup_h - -#include "CallFrame.h" -#include "Identifier.h" -#include "JSGlobalObject.h" -#include "JSObject.h" -#include "PropertySlot.h" -#include <stdio.h> -#include <wtf/Assertions.h> - -// Bug #26843: Work around Metrowerks compiler bug -#if COMPILER(WINSCW) -#define JSC_CONST_HASHTABLE -#else -#define JSC_CONST_HASHTABLE const -#endif - -namespace JSC { - // Hash table generated by the create_hash_table script. - struct HashTableValue { - const char* key; // property name - unsigned char attributes; // JSObject attributes - intptr_t value1; - intptr_t value2; -#if ENABLE(JIT) - ThunkGenerator generator; -#endif - }; - - // FIXME: There is no reason this get function can't be simpler. - // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject) - typedef PropertySlot::GetValueFunc GetFunction; - typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue value); - - class HashEntry : public FastAllocBase { - public: - void initialize(StringImpl* key, unsigned char attributes, intptr_t v1, intptr_t v2 -#if ENABLE(JIT) - , ThunkGenerator generator = 0 -#endif - ) - { - m_key = key; - m_attributes = attributes; - m_u.store.value1 = v1; - m_u.store.value2 = v2; -#if ENABLE(JIT) - m_u.function.generator = generator; -#endif - m_next = 0; - } - - void setKey(StringImpl* key) { m_key = key; } - StringImpl* key() const { return m_key; } - - unsigned char attributes() const { return m_attributes; } - -#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL) - ThunkGenerator generator() const { ASSERT(m_attributes & Function); return m_u.function.generator; } -#endif - NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; } - unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); } - - GetFunction propertyGetter() const { ASSERT(!(m_attributes & Function)); return m_u.property.get; } - PutFunction propertyPutter() const { ASSERT(!(m_attributes & Function)); return m_u.property.put; } - - intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; } - - void setNext(HashEntry *next) { m_next = next; } - HashEntry* next() const { return m_next; } - - private: - StringImpl* m_key; - unsigned char m_attributes; // JSObject attributes - - union { - struct { - intptr_t value1; - intptr_t value2; - } store; - struct { - NativeFunction functionValue; - intptr_t length; // number of arguments for function -#if ENABLE(JIT) - ThunkGenerator generator; -#endif - } function; - struct { - GetFunction get; - PutFunction put; - } property; - struct { - intptr_t value; - intptr_t unused; - } lexer; - } m_u; - - HashEntry* m_next; - }; - - struct HashTable { - - int compactSize; - int compactHashSizeMask; - - const HashTableValue* values; // Fixed values generated by script. - mutable const HashEntry* table; // Table allocated at runtime. - - ALWAYS_INLINE void initializeIfNeeded(JSGlobalData* globalData) const - { - if (!table) - createTable(globalData); - } - - ALWAYS_INLINE void initializeIfNeeded(ExecState* exec) const - { - if (!table) - createTable(&exec->globalData()); - } - - void deleteTable() const; - - // Find an entry in the table, and return the entry. - ALWAYS_INLINE const HashEntry* entry(JSGlobalData* globalData, const Identifier& identifier) const - { - initializeIfNeeded(globalData); - return entry(identifier); - } - - ALWAYS_INLINE const HashEntry* entry(ExecState* exec, const Identifier& identifier) const - { - initializeIfNeeded(exec); - return entry(identifier); - } - - private: - ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const - { - ASSERT(table); - - const HashEntry* entry = &table[identifier.impl()->existingHash() & compactHashSizeMask]; - - if (!entry->key()) - return 0; - - do { - if (entry->key() == identifier.impl()) - return entry; - entry = entry->next(); - } while (entry); - - return 0; - } - - // Convert the hash table keys to identifiers. - void createTable(JSGlobalData*) const; - }; - - void setUpStaticFunctionSlot(ExecState*, const HashEntry*, JSObject* thisObject, const Identifier& propertyName, PropertySlot&); - - /** - * This method does it all (looking in the hashtable, checking for function - * overrides, creating the function or retrieving from cache, calling - * getValueProperty in case of a non-function property, forwarding to parent if - * unknown property). - */ - template <class ThisImp, class ParentImp> - inline bool getStaticPropertySlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot) - { - const HashEntry* entry = table->entry(exec, propertyName); - - if (!entry) // not found, forward to parent - return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot); - - if (entry->attributes() & Function) - setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); - else - slot.setCacheableCustom(thisObj, entry->propertyGetter()); - - return true; - } - - template <class ThisImp, class ParentImp> - inline bool getStaticPropertyDescriptor(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) - { - const HashEntry* entry = table->entry(exec, propertyName); - - if (!entry) // not found, forward to parent - return thisObj->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor); - - PropertySlot slot; - if (entry->attributes() & Function) - setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); - else - slot.setCustom(thisObj, entry->propertyGetter()); - - descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); - return true; - } - - /** - * Simplified version of getStaticPropertySlot in case there are only functions. - * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing - * a dummy getValueProperty. - */ - template <class ParentImp> - inline bool getStaticFunctionSlot(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot) - { - if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertySlot(exec, propertyName, slot)) - return true; - - const HashEntry* entry = table->entry(exec, propertyName); - if (!entry) - return false; - - setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); - return true; - } - - /** - * Simplified version of getStaticPropertyDescriptor in case there are only functions. - * Using this instead of getStaticPropertyDescriptor allows 'this' to avoid implementing - * a dummy getValueProperty. - */ - template <class ParentImp> - inline bool getStaticFunctionDescriptor(ExecState* exec, const HashTable* table, JSObject* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) - { - if (static_cast<ParentImp*>(thisObj)->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor)) - return true; - - const HashEntry* entry = table->entry(exec, propertyName); - if (!entry) - return false; - - PropertySlot slot; - setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot); - descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); - return true; - } - - /** - * Simplified version of getStaticPropertySlot in case there are no functions, only "values". - * Using this instead of getStaticPropertySlot removes the need for a FuncImp class. - */ - template <class ThisImp, class ParentImp> - inline bool getStaticValueSlot(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertySlot& slot) - { - const HashEntry* entry = table->entry(exec, propertyName); - - if (!entry) // not found, forward to parent - return thisObj->ParentImp::getOwnPropertySlot(exec, propertyName, slot); - - ASSERT(!(entry->attributes() & Function)); - - slot.setCacheableCustom(thisObj, entry->propertyGetter()); - return true; - } - - /** - * Simplified version of getStaticPropertyDescriptor in case there are no functions, only "values". - * Using this instead of getStaticPropertyDescriptor removes the need for a FuncImp class. - */ - template <class ThisImp, class ParentImp> - inline bool getStaticValueDescriptor(ExecState* exec, const HashTable* table, ThisImp* thisObj, const Identifier& propertyName, PropertyDescriptor& descriptor) - { - const HashEntry* entry = table->entry(exec, propertyName); - - if (!entry) // not found, forward to parent - return thisObj->ParentImp::getOwnPropertyDescriptor(exec, propertyName, descriptor); - - ASSERT(!(entry->attributes() & Function)); - PropertySlot slot; - slot.setCustom(thisObj, entry->propertyGetter()); - descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); - return true; - } - - /** - * This one is for "put". - * It looks up a hash entry for the property to be set. If an entry - * is found it sets the value and returns true, else it returns false. - */ - template <class ThisImp> - inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj) - { - const HashEntry* entry = table->entry(exec, propertyName); - - if (!entry) - return false; - - if (entry->attributes() & Function) { // function: put as override property - if (LIKELY(value.isCell())) - thisObj->putDirectFunction(propertyName, value.asCell()); - else - thisObj->putDirect(propertyName, value); - } else if (!(entry->attributes() & ReadOnly)) - entry->propertyPutter()(exec, thisObj, value); - - return true; - } - - /** - * This one is for "put". - * It calls lookupPut<ThisImp>() to set the value. If that call - * returns false (meaning no entry in the hash table was found), - * then it calls put() on the ParentImp class. - */ - template <class ThisImp, class ParentImp> - inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot) - { - if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj)) - thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent - } - -} // namespace JSC - -#endif // Lookup_h diff --git a/JavaScriptCore/runtime/MarkStack.cpp b/JavaScriptCore/runtime/MarkStack.cpp deleted file mode 100644 index a350c35..0000000 --- a/JavaScriptCore/runtime/MarkStack.cpp +++ /dev/null @@ -1,40 +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. - */ - -#include "config.h" -#include "MarkStack.h" - -namespace JSC { - -size_t MarkStack::s_pageSize = 0; - -void MarkStack::compact() -{ - ASSERT(s_pageSize); - m_values.shrinkAllocation(s_pageSize); - m_markSets.shrinkAllocation(s_pageSize); -} - -} diff --git a/JavaScriptCore/runtime/MarkStack.h b/JavaScriptCore/runtime/MarkStack.h deleted file mode 100644 index 7bccadf..0000000 --- a/JavaScriptCore/runtime/MarkStack.h +++ /dev/null @@ -1,190 +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 MarkStack_h -#define MarkStack_h - -#include "JSValue.h" -#include <wtf/Noncopyable.h> -#include <wtf/OSAllocator.h> - -namespace JSC { - - class JSGlobalData; - class Register; - - enum MarkSetProperties { MayContainNullValues, NoNullValues }; - - class MarkStack : Noncopyable { - public: - MarkStack(void* jsArrayVPtr) - : m_jsArrayVPtr(jsArrayVPtr) -#if !ASSERT_DISABLED - , m_isCheckingForDefaultMarkViolation(false) - , m_isDraining(false) -#endif - { - } - - ALWAYS_INLINE void append(JSValue); - void append(JSCell*); - - ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues) - { - appendValues(reinterpret_cast<JSValue*>(values), count, properties); - } - - ALWAYS_INLINE void appendValues(JSValue* values, size_t count, MarkSetProperties properties = NoNullValues) - { - if (count) - m_markSets.append(MarkSet(values, values + count, properties)); - } - - inline void drain(); - void compact(); - - ~MarkStack() - { - ASSERT(m_markSets.isEmpty()); - ASSERT(m_values.isEmpty()); - } - - private: - void markChildren(JSCell*); - - struct MarkSet { - MarkSet(JSValue* values, JSValue* end, MarkSetProperties properties) - : m_values(values) - , m_end(end) - , m_properties(properties) - { - ASSERT(values); - } - JSValue* m_values; - JSValue* m_end; - MarkSetProperties m_properties; - }; - - static void* allocateStack(size_t size) { return OSAllocator::reserveAndCommit(size); } - static void releaseStack(void* addr, size_t size) { OSAllocator::decommitAndRelease(addr, size); } - - static void initializePagesize(); - static size_t pageSize() - { - if (!s_pageSize) - initializePagesize(); - return s_pageSize; - } - - template <typename T> struct MarkStackArray { - MarkStackArray() - : m_top(0) - , m_allocated(MarkStack::pageSize()) - , m_capacity(m_allocated / sizeof(T)) - { - m_data = reinterpret_cast<T*>(allocateStack(m_allocated)); - } - - ~MarkStackArray() - { - releaseStack(m_data, m_allocated); - } - - void expand() - { - size_t oldAllocation = m_allocated; - m_allocated *= 2; - m_capacity = m_allocated / sizeof(T); - void* newData = allocateStack(m_allocated); - memcpy(newData, m_data, oldAllocation); - releaseStack(m_data, oldAllocation); - m_data = reinterpret_cast<T*>(newData); - } - - inline void append(const T& v) - { - if (m_top == m_capacity) - expand(); - m_data[m_top++] = v; - } - - inline T removeLast() - { - ASSERT(m_top); - return m_data[--m_top]; - } - - inline T& last() - { - ASSERT(m_top); - return m_data[m_top - 1]; - } - - inline bool isEmpty() - { - return m_top == 0; - } - - inline size_t size() { return m_top; } - - inline void shrinkAllocation(size_t size) - { - ASSERT(size <= m_allocated); - ASSERT(0 == (size % MarkStack::pageSize())); - if (size == m_allocated) - return; -#if OS(WINDOWS) || OS(SYMBIAN) || PLATFORM(BREWMP) - // We cannot release a part of a region with VirtualFree. To get around this, - // we'll release the entire region and reallocate the size that we want. - releaseStack(m_data, m_allocated); - m_data = reinterpret_cast<T*>(allocateStack(size)); -#else - releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size); -#endif - m_allocated = size; - m_capacity = m_allocated / sizeof(T); - } - - private: - size_t m_top; - size_t m_allocated; - size_t m_capacity; - T* m_data; - }; - - void* m_jsArrayVPtr; - MarkStackArray<MarkSet> m_markSets; - MarkStackArray<JSCell*> m_values; - static size_t s_pageSize; - -#if !ASSERT_DISABLED - public: - bool m_isCheckingForDefaultMarkViolation; - bool m_isDraining; -#endif - }; -} - -#endif diff --git a/JavaScriptCore/runtime/MarkStackPosix.cpp b/JavaScriptCore/runtime/MarkStackPosix.cpp deleted file mode 100644 index 2a5b298..0000000 --- a/JavaScriptCore/runtime/MarkStackPosix.cpp +++ /dev/null @@ -1,43 +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. - */ - -#include "config.h" -#include "MarkStack.h" - -#if OS(UNIX) && !OS(SYMBIAN) - -#include <unistd.h> -#include <sys/mman.h> - -namespace JSC { - -void MarkStack::initializePagesize() -{ - MarkStack::s_pageSize = getpagesize(); -} - -} - -#endif diff --git a/JavaScriptCore/runtime/MarkStackSymbian.cpp b/JavaScriptCore/runtime/MarkStackSymbian.cpp deleted file mode 100644 index a3893d7..0000000 --- a/JavaScriptCore/runtime/MarkStackSymbian.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" -#include "MarkStack.h" - -#if OS(SYMBIAN) - -#include <e32hal.h> - -namespace JSC { - -void MarkStack::initializePagesize() -{ - TInt page_size; - UserHal::PageSizeInBytes(page_size); - MarkStack::s_pageSize = page_size; -} - -} - -#endif diff --git a/JavaScriptCore/runtime/MarkStackWin.cpp b/JavaScriptCore/runtime/MarkStackWin.cpp deleted file mode 100644 index 2d2a1b3..0000000 --- a/JavaScriptCore/runtime/MarkStackWin.cpp +++ /dev/null @@ -1,44 +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. - */ - -#include "config.h" -#include "MarkStack.h" - -#if OS(WINDOWS) - -#include "windows.h" - -namespace JSC { - -void MarkStack::initializePagesize() -{ - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - MarkStack::s_pageSize = system_info.dwPageSize; -} - -} - -#endif diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp deleted file mode 100644 index 080d7d2..0000000 --- a/JavaScriptCore/runtime/MathObject.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "MathObject.h" - -#include "Lookup.h" -#include "ObjectPrototype.h" -#include "Operations.h" -#include <time.h> -#include <wtf/Assertions.h> -#include <wtf/MathExtras.h> -#include <wtf/RandomNumber.h> -#include <wtf/RandomNumberSeed.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(MathObject); - -static EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncASin(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncMin(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*); -static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*); - -} - -#include "MathObject.lut.h" - -namespace JSC { - -// ------------------------------ MathObject -------------------------------- - -const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable }; - -/* Source for MathObject.lut.h -@begin mathTable - abs mathProtoFuncAbs DontEnum|Function 1 - acos mathProtoFuncACos DontEnum|Function 1 - asin mathProtoFuncASin DontEnum|Function 1 - atan mathProtoFuncATan DontEnum|Function 1 - atan2 mathProtoFuncATan2 DontEnum|Function 2 - ceil mathProtoFuncCeil DontEnum|Function 1 - cos mathProtoFuncCos DontEnum|Function 1 - exp mathProtoFuncExp DontEnum|Function 1 - floor mathProtoFuncFloor DontEnum|Function 1 - log mathProtoFuncLog DontEnum|Function 1 - max mathProtoFuncMax DontEnum|Function 2 - min mathProtoFuncMin DontEnum|Function 2 - pow mathProtoFuncPow DontEnum|Function 2 - random mathProtoFuncRandom DontEnum|Function 0 - round mathProtoFuncRound DontEnum|Function 1 - sin mathProtoFuncSin DontEnum|Function 1 - sqrt mathProtoFuncSqrt DontEnum|Function 1 - tan mathProtoFuncTan DontEnum|Function 1 -@end -*/ - -MathObject::MathObject(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : JSObjectWithGlobalObject(globalObject, structure) -{ - putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exp(1.0)), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "LN2"), jsNumber(log(2.0)), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "LN10"), jsNumber(log(10.0)), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "LOG2E"), jsNumber(1.0 / log(2.0)), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "LOG10E"), jsNumber(1.0 / log(10.0)), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "PI"), jsNumber(piDouble), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "SQRT1_2"), jsNumber(sqrt(0.5)), DontDelete | DontEnum | ReadOnly); - putDirectWithoutTransition(Identifier(exec, "SQRT2"), jsNumber(sqrt(2.0)), DontDelete | DontEnum | ReadOnly); -} - -// ECMA 15.8 - -bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot) -{ - return getStaticFunctionSlot<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, slot); -} - -bool MathObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticFunctionDescriptor<JSObject>(exec, ExecState::mathTable(exec), this, propertyName, descriptor); -} - -// ------------------------------ Functions -------------------------------- - -EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec) -{ - return JSValue::encode(jsNumber(fabs(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(acos(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(asin(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(atan(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec) -{ - double arg0 = exec->argument(0).toNumber(exec); - double arg1 = exec->argument(1).toNumber(exec); - return JSValue::encode(jsDoubleNumber(atan2(arg0, arg1))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec) -{ - return JSValue::encode(jsNumber(ceil(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(cos(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(exp(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec) -{ - return JSValue::encode(jsNumber(floor(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(log(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec) -{ - unsigned argsCount = exec->argumentCount(); - double result = -Inf; - for (unsigned k = 0; k < argsCount; ++k) { - double val = exec->argument(k).toNumber(exec); - if (isnan(val)) { - result = NaN; - break; - } - if (val > result || (val == 0 && result == 0 && !signbit(val))) - result = val; - } - return JSValue::encode(jsNumber(result)); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncMin(ExecState* exec) -{ - unsigned argsCount = exec->argumentCount(); - double result = +Inf; - for (unsigned k = 0; k < argsCount; ++k) { - double val = exec->argument(k).toNumber(exec); - if (isnan(val)) { - result = NaN; - break; - } - if (val < result || (val == 0 && result == 0 && signbit(val))) - result = val; - } - return JSValue::encode(jsNumber(result)); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec) -{ - // ECMA 15.8.2.1.13 - - double arg = exec->argument(0).toNumber(exec); - double arg2 = exec->argument(1).toNumber(exec); - - if (isnan(arg2)) - return JSValue::encode(jsNaN()); - if (isinf(arg2) && fabs(arg) == 1) - return JSValue::encode(jsNaN()); - return JSValue::encode(jsNumber(pow(arg, arg2))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(exec->lexicalGlobalObject()->weakRandomNumber())); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec) -{ - double arg = exec->argument(0).toNumber(exec); - double integer = ceil(arg); - return JSValue::encode(jsNumber(integer - (integer - arg > 0.5))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec) -{ - return JSValue::encode(exec->globalData().cachedSin(exec->argument(0).toNumber(exec))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(sqrt(exec->argument(0).toNumber(exec)))); -} - -EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec) -{ - return JSValue::encode(jsDoubleNumber(tan(exec->argument(0).toNumber(exec)))); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/MathObject.h b/JavaScriptCore/runtime/MathObject.h deleted file mode 100644 index 31fa2fe..0000000 --- a/JavaScriptCore/runtime/MathObject.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef MathObject_h -#define MathObject_h - -#include "JSObjectWithGlobalObject.h" - -namespace JSC { - - class MathObject : public JSObjectWithGlobalObject { - public: - MathObject(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; - }; - -} // namespace JSC - -#endif // MathObject_h diff --git a/JavaScriptCore/runtime/MemoryStatistics.cpp b/JavaScriptCore/runtime/MemoryStatistics.cpp deleted file mode 100644 index 7fafa9c..0000000 --- a/JavaScriptCore/runtime/MemoryStatistics.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 "MemoryStatistics.h" - -#include "ExecutableAllocator.h" -#include "JSGlobalData.h" -#include "RegisterFile.h" - -namespace JSC { - -Heap::Statistics heapStatistics(JSGlobalData* commonGlobalData) -{ - return commonGlobalData->heap.statistics(); -} - -GlobalMemoryStatistics globalMemoryStatistics() -{ - GlobalMemoryStatistics stats; - - stats.stackBytes = RegisterFile::committedByteCount(); -#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) - stats.JITBytes = ExecutableAllocator::committedByteCount(); -#else - stats.JITBytes = 0; -#endif - return stats; -} - -} - - diff --git a/JavaScriptCore/runtime/MemoryStatistics.h b/JavaScriptCore/runtime/MemoryStatistics.h deleted file mode 100644 index 1b92eb9..0000000 --- a/JavaScriptCore/runtime/MemoryStatistics.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 MemoryStatistics_h -#define MemoryStatistics_h - -#include "Collector.h" - -class JSGlobalData; - -namespace JSC { - -struct GlobalMemoryStatistics { - size_t stackBytes; - size_t JITBytes; -}; - -Heap::Statistics heapStatistics(JSGlobalData* commonGlobalData); -GlobalMemoryStatistics globalMemoryStatistics(); - -} - -#endif // MemoryStatistics_h - diff --git a/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/JavaScriptCore/runtime/NativeErrorConstructor.cpp deleted file mode 100644 index eb508eb..0000000 --- a/JavaScriptCore/runtime/NativeErrorConstructor.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "NativeErrorConstructor.h" - -#include "ErrorInstance.h" -#include "JSFunction.h" -#include "JSString.h" -#include "NativeErrorPrototype.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor); - -const ClassInfo NativeErrorConstructor::info = { "Function", &InternalFunction::info, 0, 0 }; - -NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<Structure> prototypeStructure, const UString& nameAndMessage) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, nameAndMessage)) -{ - NativeErrorPrototype* prototype = new (exec) NativeErrorPrototype(exec, globalObject, prototypeStructure, nameAndMessage, this); - - putDirect(exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5 - putDirect(exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum); - m_errorStructure = ErrorInstance::createStructure(prototype); -} - -static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState* exec) -{ - JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined(); - Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure(); - return JSValue::encode(ErrorInstance::create(exec, errorStructure, message)); -} - -ConstructType NativeErrorConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithNativeErrorConstructor; - return ConstructTypeHost; -} - -static EncodedJSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState* exec) -{ - JSValue message = exec->argumentCount() ? exec->argument(0) : jsUndefined(); - Structure* errorStructure = static_cast<NativeErrorConstructor*>(exec->callee())->errorStructure(); - return JSValue::encode(ErrorInstance::create(exec, errorStructure, message)); -} - -CallType NativeErrorConstructor::getCallData(CallData& callData) -{ - callData.native.function = callNativeErrorConstructor; - return CallTypeHost; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/NativeErrorConstructor.h b/JavaScriptCore/runtime/NativeErrorConstructor.h deleted file mode 100644 index 1ff8207..0000000 --- a/JavaScriptCore/runtime/NativeErrorConstructor.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef NativeErrorConstructor_h -#define NativeErrorConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class ErrorInstance; - class FunctionPrototype; - class NativeErrorPrototype; - - class NativeErrorConstructor : public InternalFunction { - public: - NativeErrorConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<Structure> prototypeStructure, const UString&); - - static const ClassInfo info; - - Structure* errorStructure() { return m_errorStructure.get(); } - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - - virtual const ClassInfo* classInfo() const { return &info; } - - RefPtr<Structure> m_errorStructure; - }; - -} // namespace JSC - -#endif // NativeErrorConstructor_h diff --git a/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/JavaScriptCore/runtime/NativeErrorPrototype.cpp deleted file mode 100644 index 540220a..0000000 --- a/JavaScriptCore/runtime/NativeErrorPrototype.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "NativeErrorPrototype.h" - -#include "ErrorPrototype.h" -#include "JSGlobalObject.h" -#include "JSString.h" -#include "NativeErrorConstructor.h" -#include "UString.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype); - -NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& nameAndMessage, NativeErrorConstructor* constructor) - : JSObjectWithGlobalObject(globalObject, structure) -{ - putDirect(exec->propertyNames().name, jsString(exec, nameAndMessage), 0); - putDirect(exec->propertyNames().message, jsString(exec, nameAndMessage), 0); - putDirect(exec->propertyNames().constructor, constructor, DontEnum); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/NativeErrorPrototype.h b/JavaScriptCore/runtime/NativeErrorPrototype.h deleted file mode 100644 index 30690d5..0000000 --- a/JavaScriptCore/runtime/NativeErrorPrototype.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef NativeErrorPrototype_h -#define NativeErrorPrototype_h - -#include "JSObjectWithGlobalObject.h" - -namespace JSC { - class NativeErrorConstructor; - - class NativeErrorPrototype : public JSObjectWithGlobalObject { - public: - NativeErrorPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, const UString&, NativeErrorConstructor*); - }; - -} // namespace JSC - -#endif // NativeErrorPrototype_h diff --git a/JavaScriptCore/runtime/NativeFunctionWrapper.h b/JavaScriptCore/runtime/NativeFunctionWrapper.h deleted file mode 100644 index d4eeb3b..0000000 --- a/JavaScriptCore/runtime/NativeFunctionWrapper.h +++ /dev/null @@ -1,39 +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 NativeFunctionWrapper_h -#define NativeFunctionWrapper_h - -namespace JSC { -#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL) - class JSFunction; - typedef JSFunction NativeFunctionWrapper; -#else - class PrototypeFunction; - typedef PrototypeFunction NativeFunctionWrapper; -#endif -} - -#endif diff --git a/JavaScriptCore/runtime/NumberConstructor.cpp b/JavaScriptCore/runtime/NumberConstructor.cpp deleted file mode 100644 index 5369ca0..0000000 --- a/JavaScriptCore/runtime/NumberConstructor.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "NumberConstructor.h" - -#include "Lookup.h" -#include "NumberObject.h" -#include "NumberPrototype.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(NumberConstructor); - -static JSValue numberConstructorNaNValue(ExecState*, JSValue, const Identifier&); -static JSValue numberConstructorNegInfinity(ExecState*, JSValue, const Identifier&); -static JSValue numberConstructorPosInfinity(ExecState*, JSValue, const Identifier&); -static JSValue numberConstructorMaxValue(ExecState*, JSValue, const Identifier&); -static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&); - -} // namespace JSC - -#include "NumberConstructor.lut.h" - -namespace JSC { - -const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::numberTable }; - -/* Source for NumberConstructor.lut.h -@begin numberTable - NaN numberConstructorNaNValue DontEnum|DontDelete|ReadOnly - NEGATIVE_INFINITY numberConstructorNegInfinity DontEnum|DontDelete|ReadOnly - POSITIVE_INFINITY numberConstructorPosInfinity DontEnum|DontDelete|ReadOnly - MAX_VALUE numberConstructorMaxValue DontEnum|DontDelete|ReadOnly - MIN_VALUE numberConstructorMinValue DontEnum|DontDelete|ReadOnly -@end -*/ - -NumberConstructor::NumberConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NumberPrototype* numberPrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, numberPrototype->info.className)) -{ - // Number.Prototype - putDirectWithoutTransition(exec->propertyNames().prototype, numberPrototype, DontEnum | DontDelete | ReadOnly); - - // no. of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete); -} - -bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot); -} - -bool NumberConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticValueDescriptor<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, descriptor); -} - -static JSValue numberConstructorNaNValue(ExecState*, JSValue, const Identifier&) -{ - return jsNaN(); -} - -static JSValue numberConstructorNegInfinity(ExecState*, JSValue, const Identifier&) -{ - return jsNumber(-Inf); -} - -static JSValue numberConstructorPosInfinity(ExecState*, JSValue, const Identifier&) -{ - return jsNumber(Inf); -} - -static JSValue numberConstructorMaxValue(ExecState*, JSValue, const Identifier&) -{ - return jsNumber(1.7976931348623157E+308); -} - -static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&) -{ - return jsNumber(5E-324); -} - -// ECMA 15.7.1 -static EncodedJSValue JSC_HOST_CALL constructWithNumberConstructor(ExecState* exec) -{ - NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure()); - double n = exec->argumentCount() ? exec->argument(0).toNumber(exec) : 0; - object->setInternalValue(jsNumber(n)); - return JSValue::encode(object); -} - -ConstructType NumberConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithNumberConstructor; - return ConstructTypeHost; -} - -// ECMA 15.7.2 -static EncodedJSValue JSC_HOST_CALL callNumberConstructor(ExecState* exec) -{ - return JSValue::encode(jsNumber(!exec->argumentCount() ? 0 : exec->argument(0).toNumber(exec))); -} - -CallType NumberConstructor::getCallData(CallData& callData) -{ - callData.native.function = callNumberConstructor; - return CallTypeHost; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/NumberConstructor.h b/JavaScriptCore/runtime/NumberConstructor.h deleted file mode 100644 index d8a2593..0000000 --- a/JavaScriptCore/runtime/NumberConstructor.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef NumberConstructor_h -#define NumberConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class NumberPrototype; - - class NumberConstructor : public InternalFunction { - public: - NumberConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, NumberPrototype*); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - JSValue getValueProperty(ExecState*, int token) const; - - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue proto) - { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - - virtual const ClassInfo* classInfo() const { return &info; } - }; - -} // namespace JSC - -#endif // NumberConstructor_h diff --git a/JavaScriptCore/runtime/NumberObject.cpp b/JavaScriptCore/runtime/NumberObject.cpp deleted file mode 100644 index 1a7e44c..0000000 --- a/JavaScriptCore/runtime/NumberObject.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "NumberObject.h" - -#include "JSGlobalObject.h" -#include "NumberPrototype.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(NumberObject); - -const ClassInfo NumberObject::info = { "Number", 0, 0, 0 }; - -NumberObject::NumberObject(NonNullPassRefPtr<Structure> structure) - : JSWrapperObject(structure) -{ -} - -JSValue NumberObject::getJSNumber() -{ - return internalValue(); -} - -NumberObject* constructNumber(ExecState* exec, JSValue number) -{ - NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure()); - object->setInternalValue(number); - return object; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h deleted file mode 100644 index e82b593..0000000 --- a/JavaScriptCore/runtime/NumberObject.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef NumberObject_h -#define NumberObject_h - -#include "JSWrapperObject.h" - -namespace JSC { - - class NumberObject : public JSWrapperObject { - public: - explicit NumberObject(NonNullPassRefPtr<Structure>); - - static const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = JSWrapperObject::StructureFlags; - - private: - virtual const ClassInfo* classInfo() const { return &info; } - - virtual JSValue getJSNumber(); - }; - - NumberObject* constructNumber(ExecState*, JSValue); - -} // namespace JSC - -#endif // NumberObject_h diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp deleted file mode 100644 index 0b86c00..0000000 --- a/JavaScriptCore/runtime/NumberPrototype.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - */ - -#include "config.h" -#include "NumberPrototype.h" - -#include "Error.h" -#include "JSFunction.h" -#include "JSString.h" -#include "Operations.h" -#include "PrototypeFunction.h" -#include "dtoa.h" -#include <wtf/Assertions.h> -#include <wtf/DecimalNumber.h> -#include <wtf/MathExtras.h> -#include <wtf/Vector.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(NumberPrototype); - -static EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState*); -static EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*); -static EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*); -static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*); - -// ECMA 15.7.4 - -NumberPrototype::NumberPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure) - : NumberObject(structure) -{ - setInternalValue(jsNumber(0)); - - // The constructor will be added later, after NumberConstructor has been constructed - - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum); -} - -// ------------------------------ Functions --------------------------- - -// ECMA 15.7.4.2 - 15.7.4.7 - -static ALWAYS_INLINE bool toThisNumber(JSValue thisValue, double &x) -{ - JSValue v = thisValue.getJSNumber(); - if (UNLIKELY(!v)) - return false; - x = v.uncheckedGetNumber(); - return true; -} - -static ALWAYS_INLINE bool getIntegerArgumentInRange(ExecState* exec, int low, int high, int& result, bool& isUndefined) -{ - result = 0; - isUndefined = false; - - JSValue argument0 = exec->argument(0); - if (argument0.isUndefined()) { - isUndefined = true; - return true; - } - - double asDouble = argument0.toInteger(exec); - if (asDouble < low || asDouble > high) - return false; - - result = static_cast<int>(asDouble); - return true; -} - -// toExponential converts a number to a string, always formatting as an expoential. -// This method takes an optional argument specifying a number of *decimal places* -// to round the significand to (or, put another way, this method optionally rounds -// to argument-plus-one significant figures). -EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec) -{ - // Get x (the double value of this, which should be a Number). - double x; - if (!toThisNumber(exec->hostThisValue(), x)) - return throwVMTypeError(exec); - - // Get the argument. - int decimalPlacesInExponent; - bool isUndefined; - if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined)) - return throwVMError(exec, createRangeError(exec, "toExponential() argument must be between 0 and 20")); - - // Handle NaN and Infinity. - if (isnan(x) || isinf(x)) - return JSValue::encode(jsString(exec, UString::number(x))); - - // Round if the argument is not undefined, always format as exponential. - NumberToStringBuffer buffer; - unsigned length = isUndefined - ? DecimalNumber(x).toStringExponential(buffer, WTF::NumberToStringBufferLength) - : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer, WTF::NumberToStringBufferLength); - - return JSValue::encode(jsString(exec, UString(buffer, length))); -} - -// toFixed converts a number to a string, always formatting as an a decimal fraction. -// This method takes an argument specifying a number of decimal places to round the -// significand to. However when converting large values (1e+21 and above) this -// method will instead fallback to calling ToString. -EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec) -{ - // Get x (the double value of this, which should be a Number). - JSValue thisValue = exec->hostThisValue(); - JSValue v = thisValue.getJSNumber(); - if (!v) - return throwVMTypeError(exec); - double x = v.uncheckedGetNumber(); - - // Get the argument. - int decimalPlaces; - bool isUndefined; // This is ignored; undefined treated as 0. - if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined)) - return throwVMError(exec, createRangeError(exec, "toFixed() argument must be between 0 and 20")); - - // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)" - // This also covers Ininity, and structure the check so that NaN - // values are also handled by numberToString - if (!(fabs(x) < 1e+21)) - return JSValue::encode(jsString(exec, UString::number(x))); - - // The check above will return false for NaN or Infinity, these will be - // handled by numberToString. - ASSERT(!isnan(x) && !isinf(x)); - - // Convert to decimal with rounding, and format as decimal. - NumberToStringBuffer buffer; - unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer, WTF::NumberToStringBufferLength); - return JSValue::encode(jsString(exec, UString(buffer, length))); -} - -// toPrecision converts a number to a string, takeing an argument specifying a -// number of significant figures to round the significand to. For positive -// exponent, all values that can be represented using a decimal fraction will -// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a -// decimal, whilst 1000 is converted to the exponential representation 1.00e+3. -// For negative exponents values >= 1e-6 are formated as decimal fractions, -// with smaller values converted to exponential representation. -EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec) -{ - // Get x (the double value of this, which should be a Number). - JSValue thisValue = exec->hostThisValue(); - JSValue v = thisValue.getJSNumber(); - if (!v) - return throwVMTypeError(exec); - double x = v.uncheckedGetNumber(); - - // Get the argument. - int significantFigures; - bool isUndefined; - if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined)) - return throwVMError(exec, createRangeError(exec, "toPrecision() argument must be between 1 and 21")); - - // To precision called with no argument is treated as ToString. - if (isUndefined) - return JSValue::encode(jsString(exec, UString::number(x))); - - // Handle NaN and Infinity. - if (isnan(x) || isinf(x)) - return JSValue::encode(jsString(exec, UString::number(x))); - - // Convert to decimal with rounding. - DecimalNumber number(x, RoundingSignificantFigures, significantFigures); - // If number is in the range 1e-6 <= x < pow(10, significantFigures) then format - // as decimal. Otherwise, format the number as an exponential. Decimal format - // demands a minimum of (exponent + 1) digits to represent a number, for example - // 1234 (1.234e+3) requires 4 digits. (See ECMA-262 15.7.4.7.10.c) - NumberToStringBuffer buffer; - unsigned length = number.exponent() >= -6 && number.exponent() < significantFigures - ? number.toStringDecimal(buffer, WTF::NumberToStringBufferLength) - : number.toStringExponential(buffer, WTF::NumberToStringBufferLength); - return JSValue::encode(jsString(exec, UString(buffer, length))); -} - -EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - JSValue v = thisValue.getJSNumber(); - if (!v) - return throwVMTypeError(exec); - - JSValue radixValue = exec->argument(0); - int radix; - if (radixValue.isInt32()) - radix = radixValue.asInt32(); - else if (radixValue.isUndefined()) - radix = 10; - else - radix = static_cast<int>(radixValue.toInteger(exec)); // nan -> 0 - - if (radix == 10) - return JSValue::encode(jsString(exec, v.toString(exec))); - - static const char* const digits = "0123456789abcdefghijklmnopqrstuvwxyz"; - - // Fast path for number to character conversion. - if (radix == 36) { - if (v.isInt32()) { - int x = v.asInt32(); - if (static_cast<unsigned>(x) < 36) { // Exclude negatives - JSGlobalData* globalData = &exec->globalData(); - return JSValue::encode(globalData->smallStrings.singleCharacterString(globalData, digits[x])); - } - } - } - - if (radix < 2 || radix > 36) - return throwVMError(exec, createRangeError(exec, "toString() radix argument must be between 2 and 36")); - - // INT_MAX results in 1024 characters left of the dot with radix 2 - // give the same space on the right side. safety checks are in place - // unless someone finds a precise rule. - char s[2048 + 3]; - const char* lastCharInString = s + sizeof(s) - 1; - double x = v.uncheckedGetNumber(); - if (isnan(x) || isinf(x)) - return JSValue::encode(jsString(exec, UString::number(x))); - - bool isNegative = x < 0.0; - if (isNegative) - x = -x; - - double integerPart = floor(x); - char* decimalPoint = s + sizeof(s) / 2; - - // convert integer portion - char* p = decimalPoint; - double d = integerPart; - do { - int remainderDigit = static_cast<int>(fmod(d, radix)); - *--p = digits[remainderDigit]; - d /= radix; - } while ((d <= -1.0 || d >= 1.0) && s < p); - - if (isNegative) - *--p = '-'; - char* startOfResultString = p; - ASSERT(s <= startOfResultString); - - d = x - integerPart; - p = decimalPoint; - const double epsilon = 0.001; // TODO: guessed. base on radix ? - bool hasFractionalPart = (d < -epsilon || d > epsilon); - if (hasFractionalPart) { - *p++ = '.'; - do { - d *= radix; - const int digit = static_cast<int>(d); - *p++ = digits[digit]; - d -= digit; - } while ((d < -epsilon || d > epsilon) && p < lastCharInString); - } - *p = '\0'; - ASSERT(p < s + sizeof(s)); - - return JSValue::encode(jsString(exec, startOfResultString)); -} - -EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - // FIXME: Not implemented yet. - - JSValue v = thisValue.getJSNumber(); - if (!v) - return throwVMTypeError(exec); - - return JSValue::encode(jsString(exec, v.toString(exec))); -} - -EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - JSValue v = thisValue.getJSNumber(); - if (!v) - return throwVMTypeError(exec); - - return JSValue::encode(v); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/NumberPrototype.h b/JavaScriptCore/runtime/NumberPrototype.h deleted file mode 100644 index 78b690e..0000000 --- a/JavaScriptCore/runtime/NumberPrototype.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef NumberPrototype_h -#define NumberPrototype_h - -#include "NumberObject.h" - -namespace JSC { - - class NumberPrototype : public NumberObject { - public: - NumberPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure); - }; - -} // namespace JSC - -#endif // NumberPrototype_h diff --git a/JavaScriptCore/runtime/NumericStrings.h b/JavaScriptCore/runtime/NumericStrings.h deleted file mode 100644 index d65f142..0000000 --- a/JavaScriptCore/runtime/NumericStrings.h +++ /dev/null @@ -1,98 +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 NumericStrings_h -#define NumericStrings_h - -#include "UString.h" -#include <wtf/FixedArray.h> -#include <wtf/HashFunctions.h> - -namespace JSC { - - class NumericStrings { - public: - UString add(double d) - { - CacheEntry<double>& entry = lookup(d); - if (d == entry.key && !entry.value.isNull()) - return entry.value; - entry.key = d; - entry.value = UString::number(d); - return entry.value; - } - - UString add(int i) - { - if (static_cast<unsigned>(i) < cacheSize) - return lookupSmallString(static_cast<unsigned>(i)); - CacheEntry<int>& entry = lookup(i); - if (i == entry.key && !entry.value.isNull()) - return entry.value; - entry.key = i; - entry.value = UString::number(i); - return entry.value; - } - - UString add(unsigned i) - { - if (i < cacheSize) - return lookupSmallString(static_cast<unsigned>(i)); - CacheEntry<unsigned>& entry = lookup(i); - if (i == entry.key && !entry.value.isNull()) - return entry.value; - entry.key = i; - entry.value = UString::number(i); - return entry.value; - } - private: - static const size_t cacheSize = 64; - - template<typename T> - struct CacheEntry { - T key; - UString value; - }; - - CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } - CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; } - CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; } - const UString& lookupSmallString(unsigned i) - { - ASSERT(i < cacheSize); - if (smallIntCache[i].isNull()) - smallIntCache[i] = UString::number(i); - return smallIntCache[i]; - } - - FixedArray<CacheEntry<double>, cacheSize> doubleCache; - FixedArray<CacheEntry<int>, cacheSize> intCache; - FixedArray<CacheEntry<unsigned>, cacheSize> unsignedCache; - FixedArray<UString, cacheSize> smallIntCache; - }; - -} // namespace JSC - -#endif // NumericStrings_h diff --git a/JavaScriptCore/runtime/ObjectConstructor.cpp b/JavaScriptCore/runtime/ObjectConstructor.cpp deleted file mode 100644 index ca3dcd7..0000000 --- a/JavaScriptCore/runtime/ObjectConstructor.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "ObjectConstructor.h" - -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSFunction.h" -#include "JSArray.h" -#include "JSGlobalObject.h" -#include "ObjectPrototype.h" -#include "PropertyDescriptor.h" -#include "PropertyNameArray.h" -#include "PrototypeFunction.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor); - -static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState*); - -ObjectConstructor::ObjectConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure) -: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, "Object")) -{ - // ECMA 15.2.3.1 - putDirectWithoutTransition(exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly); - - // no. of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete); - - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().getOwnPropertyNames, objectConstructorGetOwnPropertyNames), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().defineProperties, objectConstructorDefineProperties), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().create, objectConstructorCreate), DontEnum); -} - -// ECMA 15.2.2 -static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args) -{ - JSValue arg = args.at(0); - if (arg.isUndefinedOrNull()) - return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure()); - return arg.toObject(exec); -} - -static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructObject(exec, args)); -} - -ConstructType ObjectConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithObjectConstructor; - return ConstructTypeHost; -} - -static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructObject(exec, args)); -} - -CallType ObjectConstructor::getCallData(CallData& callData) -{ - callData.native.function = callObjectConstructor; - return CallTypeHost; -} - -EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec) -{ - if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested prototype of a value that is not an object.")); - return JSValue::encode(asObject(exec->argument(0))->prototype()); -} - -EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec) -{ - if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested property descriptor of a value that is not an object.")); - UString propertyName = exec->argument(1).toString(exec); - if (exec->hadException()) - return JSValue::encode(jsNull()); - JSObject* object = asObject(exec->argument(0)); - PropertyDescriptor descriptor; - if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor)) - return JSValue::encode(jsUndefined()); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); - - JSObject* description = constructEmptyObject(exec); - if (!descriptor.isAccessorDescriptor()) { - description->putDirect(exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0); - description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0); - } else { - description->putDirect(exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0); - description->putDirect(exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0); - } - - description->putDirect(exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0); - description->putDirect(exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0); - - return JSValue::encode(description); -} - -// FIXME: Use the enumeration cache. -EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec) -{ - if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested property names of a value that is not an object.")); - PropertyNameArray properties(exec); - asObject(exec->argument(0))->getOwnPropertyNames(exec, properties, IncludeDontEnumProperties); - JSArray* names = constructEmptyArray(exec); - size_t numProperties = properties.size(); - for (size_t i = 0; i < numProperties; i++) - names->push(exec, jsOwnedString(exec, properties[i].ustring())); - return JSValue::encode(names); -} - -// FIXME: Use the enumeration cache. -EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec) -{ - if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested keys of a value that is not an object.")); - PropertyNameArray properties(exec); - asObject(exec->argument(0))->getOwnPropertyNames(exec, properties); - JSArray* keys = constructEmptyArray(exec); - size_t numProperties = properties.size(); - for (size_t i = 0; i < numProperties; i++) - keys->push(exec, jsOwnedString(exec, properties[i].ustring())); - return JSValue::encode(keys); -} - -// ES5 8.10.5 ToPropertyDescriptor -static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc) -{ - if (!in.isObject()) { - throwError(exec, createTypeError(exec, "Property description must be an object.")); - return false; - } - JSObject* description = asObject(in); - - PropertySlot enumerableSlot(description); - if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) { - desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec)); - if (exec->hadException()) - return false; - } - - PropertySlot configurableSlot(description); - if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) { - desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec)); - if (exec->hadException()) - return false; - } - - JSValue value; - PropertySlot valueSlot(description); - if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) { - desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value)); - if (exec->hadException()) - return false; - } - - PropertySlot writableSlot(description); - if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) { - desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec)); - if (exec->hadException()) - return false; - } - - PropertySlot getSlot(description); - if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) { - JSValue get = getSlot.getValue(exec, exec->propertyNames().get); - if (exec->hadException()) - return false; - if (!get.isUndefined()) { - CallData callData; - if (getCallData(get, callData) == CallTypeNone) { - throwError(exec, createTypeError(exec, "Getter must be a function.")); - return false; - } - } else - get = JSValue(); - desc.setGetter(get); - } - - PropertySlot setSlot(description); - if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) { - JSValue set = setSlot.getValue(exec, exec->propertyNames().set); - if (exec->hadException()) - return false; - if (!set.isUndefined()) { - CallData callData; - if (getCallData(set, callData) == CallTypeNone) { - throwError(exec, createTypeError(exec, "Setter must be a function.")); - return false; - } - } else - set = JSValue(); - - desc.setSetter(set); - } - - if (!desc.isAccessorDescriptor()) - return true; - - if (desc.value()) { - throwError(exec, createTypeError(exec, "Invalid property. 'value' present on property with getter or setter.")); - return false; - } - - if (desc.writablePresent()) { - throwError(exec, createTypeError(exec, "Invalid property. 'writable' present on property with getter or setter.")); - return false; - } - return true; -} - -EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec) -{ - if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects.")); - JSObject* O = asObject(exec->argument(0)); - UString propertyName = exec->argument(1).toString(exec); - if (exec->hadException()) - return JSValue::encode(jsNull()); - PropertyDescriptor descriptor; - if (!toPropertyDescriptor(exec, exec->argument(2), descriptor)) - return JSValue::encode(jsNull()); - ASSERT((descriptor.attributes() & (Getter | Setter)) || (!descriptor.isAccessorDescriptor())); - ASSERT(!exec->hadException()); - O->defineOwnProperty(exec, Identifier(exec, propertyName), descriptor, true); - return JSValue::encode(O); -} - -static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* properties) -{ - PropertyNameArray propertyNames(exec); - asObject(properties)->getOwnPropertyNames(exec, propertyNames); - size_t numProperties = propertyNames.size(); - Vector<PropertyDescriptor> descriptors; - MarkedArgumentBuffer markBuffer; - for (size_t i = 0; i < numProperties; i++) { - PropertySlot slot; - JSValue prop = properties->get(exec, propertyNames[i]); - if (exec->hadException()) - return jsNull(); - PropertyDescriptor descriptor; - if (!toPropertyDescriptor(exec, prop, descriptor)) - return jsNull(); - descriptors.append(descriptor); - // Ensure we mark all the values that we're accumulating - if (descriptor.isDataDescriptor() && descriptor.value()) - markBuffer.append(descriptor.value()); - if (descriptor.isAccessorDescriptor()) { - if (descriptor.getter()) - markBuffer.append(descriptor.getter()); - if (descriptor.setter()) - markBuffer.append(descriptor.setter()); - } - } - for (size_t i = 0; i < numProperties; i++) { - object->defineOwnProperty(exec, propertyNames[i], descriptors[i], true); - if (exec->hadException()) - return jsNull(); - } - return object; -} - -EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec) -{ - if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects.")); - if (!exec->argument(1).isObject()) - return throwVMError(exec, createTypeError(exec, "Property descriptor list must be an Object.")); - return JSValue::encode(defineProperties(exec, asObject(exec->argument(0)), asObject(exec->argument(1)))); -} - -EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec) -{ - if (!exec->argument(0).isObject() && !exec->argument(0).isNull()) - return throwVMError(exec, createTypeError(exec, "Object prototype may only be an Object or null.")); - JSObject* newObject = constructEmptyObject(exec); - newObject->setPrototype(exec->argument(0)); - if (exec->argument(1).isUndefined()) - return JSValue::encode(newObject); - if (!exec->argument(1).isObject()) - return throwVMError(exec, createTypeError(exec, "Property descriptor list must be an Object.")); - return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1)))); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ObjectConstructor.h b/JavaScriptCore/runtime/ObjectConstructor.h deleted file mode 100644 index 04a3c1a..0000000 --- a/JavaScriptCore/runtime/ObjectConstructor.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ObjectConstructor_h -#define ObjectConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class ObjectPrototype; - - class ObjectConstructor : public InternalFunction { - public: - ObjectConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, ObjectPrototype*, Structure* prototypeFunctionStructure); - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - -} // namespace JSC - -#endif // ObjectConstructor_h diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp deleted file mode 100644 index 57a8a31..0000000 --- a/JavaScriptCore/runtime/ObjectPrototype.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "ObjectPrototype.h" - -#include "Error.h" -#include "JSFunction.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "PrototypeFunction.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype); - -static EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*); -static EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*); - -ObjectPrototype::ObjectPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure) - : JSObject(stucture) - , m_hasNoPropertiesWithUInt32Names(true) -{ - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum); - - // Mozilla extensions - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum); -} - -void ObjectPrototype::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - JSObject::put(exec, propertyName, value, slot); - - if (m_hasNoPropertiesWithUInt32Names) { - bool isUInt32; - propertyName.toUInt32(isUInt32); - m_hasNoPropertiesWithUInt32Names = !isUInt32; - } -} - -bool ObjectPrototype::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) -{ - if (m_hasNoPropertiesWithUInt32Names) - return false; - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -// ------------------------------ Functions -------------------------------- - -// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7 - -EncodedJSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(thisValue.toThisObject(exec)); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, exec->argument(0).toString(exec))))); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - JSObject* thisObj = thisValue.toThisObject(exec); - - if (!exec->argument(0).isObject()) - return JSValue::encode(jsBoolean(false)); - - JSValue v = asObject(exec->argument(0))->prototype(); - - while (true) { - if (!v.isObject()) - return JSValue::encode(jsBoolean(false)); - if (v == thisObj) - return JSValue::encode(jsBoolean(true)); - v = asObject(v)->prototype(); - } -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - CallData callData; - if (getCallData(exec->argument(1), callData) == CallTypeNone) - return throwVMError(exec, createSyntaxError(exec, "invalid getter usage")); - thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1))); - return JSValue::encode(jsUndefined()); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - CallData callData; - if (getCallData(exec->argument(1), callData) == CallTypeNone) - return throwVMError(exec, createSyntaxError(exec, "invalid setter usage")); - thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, exec->argument(0).toString(exec)), asObject(exec->argument(1))); - return JSValue::encode(jsUndefined()); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, exec->argument(0).toString(exec)))); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, exec->argument(0).toString(exec)))); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, exec->argument(0).toString(exec))))); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(thisValue.toThisJSString(exec)); -} - -EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisValue.toThisObject(exec)->className(), "]")); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ObjectPrototype.h b/JavaScriptCore/runtime/ObjectPrototype.h deleted file mode 100644 index 0382ae4..0000000 --- a/JavaScriptCore/runtime/ObjectPrototype.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ObjectPrototype_h -#define ObjectPrototype_h - -#include "JSObject.h" - -namespace JSC { - - class ObjectPrototype : public JSObject { - public: - ObjectPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure); - - private: - virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - - bool m_hasNoPropertiesWithUInt32Names; - }; - - EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*); - -} // namespace JSC - -#endif // ObjectPrototype_h diff --git a/JavaScriptCore/runtime/Operations.cpp b/JavaScriptCore/runtime/Operations.cpp deleted file mode 100644 index f129a80..0000000 --- a/JavaScriptCore/runtime/Operations.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "Operations.h" - -#include "Error.h" -#include "JSObject.h" -#include "JSString.h" -#include <math.h> -#include <stdio.h> -#include <wtf/MathExtras.h> - -namespace JSC { - -bool JSValue::equalSlowCase(ExecState* exec, JSValue v1, JSValue v2) -{ - return equalSlowCaseInline(exec, v1, v2); -} - -bool JSValue::strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2) -{ - return strictEqualSlowCaseInline(exec, v1, v2); -} - -NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2) -{ - // exception for the Date exception in defaultValue() - JSValue p1 = v1.toPrimitive(callFrame); - JSValue p2 = v2.toPrimitive(callFrame); - - if (p1.isString()) { - return p2.isString() - ? jsString(callFrame, asString(p1), asString(p2)) - : jsString(callFrame, asString(p1), p2.toString(callFrame)); - } - if (p2.isString()) - return jsString(callFrame, p1.toString(callFrame), asString(p2)); - - return jsNumber(p1.toNumber(callFrame) + p2.toNumber(callFrame)); -} - -JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v) -{ - if (v.isUndefined()) - return jsNontrivialString(callFrame, "undefined"); - if (v.isBoolean()) - return jsNontrivialString(callFrame, "boolean"); - if (v.isNumber()) - return jsNontrivialString(callFrame, "number"); - if (v.isString()) - return jsNontrivialString(callFrame, "string"); - if (v.isObject()) { - // Return "undefined" for objects that should be treated - // as null when doing comparisons. - if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined()) - return jsNontrivialString(callFrame, "undefined"); - CallData callData; - if (asObject(v)->getCallData(callData) != CallTypeNone) - return jsNontrivialString(callFrame, "function"); - } - return jsNontrivialString(callFrame, "object"); -} - -bool jsIsObjectType(JSValue v) -{ - if (!v.isCell()) - return v.isNull(); - - JSType type = v.asCell()->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/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h deleted file mode 100644 index 1252345..0000000 --- a/JavaScriptCore/runtime/Operations.h +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Operations_h -#define Operations_h - -#include "ExceptionHelpers.h" -#include "Interpreter.h" -#include "JSImmediate.h" -#include "JSNumberCell.h" -#include "JSString.h" - -namespace JSC { - - NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue); - JSValue jsTypeStringForValue(CallFrame*, JSValue); - bool jsIsObjectType(JSValue); - bool jsIsFunctionType(JSValue); - - ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2) - { - unsigned length1 = s1->length(); - if (!length1) - return s2; - unsigned length2 = s2->length(); - if (!length2) - return s1; - if ((length1 + length2) < length1) - return throwOutOfMemoryError(exec); - - unsigned fiberCount = s1->fiberCount() + s2->fiberCount(); - JSGlobalData* globalData = &exec->globalData(); - - if (fiberCount <= JSString::s_maxInternalRopeLength) - return new (globalData) JSString(globalData, fiberCount, s1, s2); - - JSString::RopeBuilder ropeBuilder(fiberCount); - if (UNLIKELY(ropeBuilder.isOutOfMemory())) - return throwOutOfMemoryError(exec); - ropeBuilder.append(s1); - ropeBuilder.append(s2); - return new (globalData) JSString(globalData, ropeBuilder.release()); - } - - ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2) - { - unsigned length1 = u1.length(); - if (!length1) - return s2; - unsigned length2 = s2->length(); - if (!length2) - return jsString(exec, u1); - if ((length1 + length2) < length1) - return throwOutOfMemoryError(exec); - - unsigned fiberCount = 1 + s2->fiberCount(); - JSGlobalData* globalData = &exec->globalData(); - - if (fiberCount <= JSString::s_maxInternalRopeLength) - return new (globalData) JSString(globalData, fiberCount, u1, s2); - - JSString::RopeBuilder ropeBuilder(fiberCount); - if (UNLIKELY(ropeBuilder.isOutOfMemory())) - return throwOutOfMemoryError(exec); - ropeBuilder.append(u1); - ropeBuilder.append(s2); - return new (globalData) JSString(globalData, ropeBuilder.release()); - } - - ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2) - { - unsigned length1 = s1->length(); - if (!length1) - return jsString(exec, u2); - unsigned length2 = u2.length(); - if (!length2) - return s1; - if ((length1 + length2) < length1) - return throwOutOfMemoryError(exec); - - unsigned fiberCount = s1->fiberCount() + 1; - JSGlobalData* globalData = &exec->globalData(); - - if (fiberCount <= JSString::s_maxInternalRopeLength) - return new (globalData) JSString(globalData, fiberCount, s1, u2); - - JSString::RopeBuilder ropeBuilder(fiberCount); - if (UNLIKELY(ropeBuilder.isOutOfMemory())) - return throwOutOfMemoryError(exec); - ropeBuilder.append(s1); - ropeBuilder.append(u2); - return new (globalData) JSString(globalData, ropeBuilder.release()); - } - - ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2) - { - unsigned length1 = u1.length(); - if (!length1) - return jsString(exec, u2); - unsigned length2 = u2.length(); - if (!length2) - return jsString(exec, u1); - if ((length1 + length2) < length1) - return throwOutOfMemoryError(exec); - - JSGlobalData* globalData = &exec->globalData(); - return new (globalData) JSString(globalData, u1, u2); - } - - ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3) - { - unsigned length1 = u1.length(); - unsigned length2 = u2.length(); - unsigned length3 = u3.length(); - if (!length1) - return jsString(exec, u2, u3); - if (!length2) - return jsString(exec, u1, u3); - if (!length3) - return jsString(exec, u1, u2); - - if ((length1 + length2) < length1) - return throwOutOfMemoryError(exec); - if ((length1 + length2 + length3) < length3) - return throwOutOfMemoryError(exec); - - JSGlobalData* globalData = &exec->globalData(); - return new (globalData) JSString(globalData, u1, u2, u3); - } - - ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count) - { - ASSERT(count >= 3); - - unsigned fiberCount = 0; - for (unsigned i = 0; i < count; ++i) { - JSValue v = strings[i].jsValue(); - if (LIKELY(v.isString())) - fiberCount += asString(v)->fiberCount(); - else - ++fiberCount; - } - - JSGlobalData* globalData = &exec->globalData(); - if (fiberCount == 3) - return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue()); - - JSString::RopeBuilder ropeBuilder(fiberCount); - if (UNLIKELY(ropeBuilder.isOutOfMemory())) - return throwOutOfMemoryError(exec); - - unsigned length = 0; - bool overflow = false; - - for (unsigned i = 0; i < count; ++i) { - JSValue v = strings[i].jsValue(); - if (LIKELY(v.isString())) - ropeBuilder.append(asString(v)); - else - ropeBuilder.append(v.toString(exec)); - - unsigned newLength = ropeBuilder.length(); - if (newLength < length) - overflow = true; - length = newLength; - } - - if (overflow) - return throwOutOfMemoryError(exec); - - return new (globalData) JSString(globalData, ropeBuilder.release()); - } - - ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue) - { - unsigned fiberCount = 0; - if (LIKELY(thisValue.isString())) - fiberCount += asString(thisValue)->fiberCount(); - else - ++fiberCount; - for (unsigned i = 0; i < exec->argumentCount(); ++i) { - JSValue v = exec->argument(i); - if (LIKELY(v.isString())) - fiberCount += asString(v)->fiberCount(); - else - ++fiberCount; - } - - JSString::RopeBuilder ropeBuilder(fiberCount); - if (UNLIKELY(ropeBuilder.isOutOfMemory())) - return throwOutOfMemoryError(exec); - - if (LIKELY(thisValue.isString())) - ropeBuilder.append(asString(thisValue)); - else - ropeBuilder.append(thisValue.toString(exec)); - - unsigned length = 0; - bool overflow = false; - - for (unsigned i = 0; i < exec->argumentCount(); ++i) { - JSValue v = exec->argument(i); - if (LIKELY(v.isString())) - ropeBuilder.append(asString(v)); - else - ropeBuilder.append(v.toString(exec)); - - unsigned newLength = ropeBuilder.length(); - if (newLength < length) - overflow = true; - length = newLength; - } - - if (overflow) - return throwOutOfMemoryError(exec); - - JSGlobalData* globalData = &exec->globalData(); - return new (globalData) JSString(globalData, ropeBuilder.release()); - } - - // ECMA 11.9.3 - inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2) - { - if (v1.isInt32() && v2.isInt32()) - return v1 == v2; - - return equalSlowCase(exec, v1, v2); - } - - ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue 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(exec) == asString(v2)->value(exec); - - if (v1.isUndefinedOrNull()) { - if (v2.isUndefinedOrNull()) - return true; - if (!v2.isCell()) - return false; - return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined(); - } - - if (v2.isUndefinedOrNull()) { - if (!v1.isCell()) - 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 (v1.isInt32() && v2.isInt32()) - return v1 == v2; - continue; - } - - if (v2.isObject()) { - JSValue p2 = v2.toPrimitive(exec); - if (exec->hadException()) - return false; - v2 = p2; - if (v1.isInt32() && v2.isInt32()) - 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(ExecState* exec, JSValue v1, JSValue v2) - { - ASSERT(v1.isCell() && v2.isCell()); - - if (v1.asCell()->isString() && v2.asCell()->isString()) - return asString(v1)->value(exec) == asString(v2)->value(exec); - - return v1 == v2; - } - - inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2) - { - if (v1.isInt32() && v2.isInt32()) - return v1 == v2; - - if (v1.isNumber() && v2.isNumber()) - return v1.uncheckedGetNumber() == v2.uncheckedGetNumber(); - - if (!v1.isCell() || !v2.isCell()) - return v1 == v2; - - return strictEqualSlowCaseInline(exec, v1, v2); - } - - ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) - { - if (v1.isInt32() && v2.isInt32()) - return v1.asInt32() < v2.asInt32(); - - 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(callFrame) < asString(v2)->value(callFrame); - - 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(callFrame) < asString(p2)->value(callFrame); - } - - inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2) - { - if (v1.isInt32() && v2.isInt32()) - return v1.asInt32() <= v2.asInt32(); - - 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(callFrame) < asString(v1)->value(callFrame)); - - 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(callFrame) < asString(p1)->value(callFrame)); - } - - // 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 = 0.0, right; - if (v1.getNumber(left) && v2.getNumber(right)) - return jsNumber(left + right); - - if (v1.isString()) { - return v2.isString() - ? jsString(callFrame, asString(v1), asString(v2)) - : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame)); - } - - // All other cases are pretty uncommon - return jsAddSlowCase(callFrame, v1, v2); - } - - inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset) - { - JSCell* cell = base.asCell(); - size_t count = 0; - - while (slotBase != cell) { - JSValue v = cell->structure()->prototypeForLookup(callFrame); - - // If we didn't find slotBase in base's prototype chain, then base - // must be a proxy for another object. - - if (v.isNull()) - return 0; - - cell = v.asCell(); - - // 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)->flattenDictionaryObject(); - if (slotBase == cell) - slotOffset = cell->structure()->get(propertyName); - } - - ++count; - } - - ASSERT(count); - return count; - } - - inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base) - { - size_t count = 0; - while (1) { - JSValue v = base->structure()->prototypeForLookup(callFrame); - if (v.isNull()) - return count; - - base = v.asCell(); - - // Since we're accessing a prototype in a loop, it's a good bet that it - // should not be treated as a dictionary. - if (base->structure()->isDictionary()) - asObject(base)->flattenDictionaryObject(); - - ++count; - } - } - - ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain, bool isStrictPut) - { - 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) - return isStrictPut ? JSValue() : base; - if (base->getPropertySlot(callFrame, property, slot)) - return base; - - iter = next; - ++next; - } - - ASSERT_NOT_REACHED(); - return JSValue(); - } -} // namespace JSC - -#endif // Operations_h diff --git a/JavaScriptCore/runtime/PropertyDescriptor.cpp b/JavaScriptCore/runtime/PropertyDescriptor.cpp deleted file mode 100644 index 558ae28..0000000 --- a/JavaScriptCore/runtime/PropertyDescriptor.cpp +++ /dev/null @@ -1,195 +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. - */ - - -#include "config.h" - -#include "PropertyDescriptor.h" - -#include "GetterSetter.h" -#include "JSObject.h" -#include "Operations.h" - -namespace JSC { -unsigned PropertyDescriptor::defaultAttributes = (DontDelete << 1) - 1; - -bool PropertyDescriptor::writable() const -{ - ASSERT(!isAccessorDescriptor()); - return !(m_attributes & ReadOnly); -} - -bool PropertyDescriptor::enumerable() const -{ - return !(m_attributes & DontEnum); -} - -bool PropertyDescriptor::configurable() const -{ - return !(m_attributes & DontDelete); -} - -bool PropertyDescriptor::isDataDescriptor() const -{ - return m_value || (m_seenAttributes & WritablePresent); -} - -bool PropertyDescriptor::isGenericDescriptor() const -{ - return !isAccessorDescriptor() && !isDataDescriptor(); -} - -bool PropertyDescriptor::isAccessorDescriptor() const -{ - return m_getter || m_setter; -} - -void PropertyDescriptor::setUndefined() -{ - m_value = jsUndefined(); - m_attributes = ReadOnly | DontDelete | DontEnum; -} - -JSValue PropertyDescriptor::getter() const -{ - ASSERT(isAccessorDescriptor()); - return m_getter; -} - -JSValue PropertyDescriptor::setter() const -{ - ASSERT(isAccessorDescriptor()); - return m_setter; -} - -void PropertyDescriptor::setDescriptor(JSValue value, unsigned attributes) -{ - ASSERT(value); - m_attributes = attributes; - if (attributes & (Getter | Setter)) { - GetterSetter* accessor = asGetterSetter(value); - m_getter = accessor->getter(); - m_setter = accessor->setter(); - ASSERT(m_getter || m_setter); - m_seenAttributes = EnumerablePresent | ConfigurablePresent; - m_attributes &= ~ReadOnly; - } else { - m_value = value; - m_seenAttributes = EnumerablePresent | ConfigurablePresent | WritablePresent; - } -} - -void PropertyDescriptor::setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes) -{ - ASSERT(attributes & (Getter | Setter)); - ASSERT(getter || setter); - m_attributes = attributes; - m_getter = getter; - m_setter = setter; - m_attributes &= ~ReadOnly; - m_seenAttributes = EnumerablePresent | ConfigurablePresent; -} - -void PropertyDescriptor::setWritable(bool writable) -{ - if (writable) - m_attributes &= ~ReadOnly; - else - m_attributes |= ReadOnly; - m_seenAttributes |= WritablePresent; -} - -void PropertyDescriptor::setEnumerable(bool enumerable) -{ - if (enumerable) - m_attributes &= ~DontEnum; - else - m_attributes |= DontEnum; - m_seenAttributes |= EnumerablePresent; -} - -void PropertyDescriptor::setConfigurable(bool configurable) -{ - if (configurable) - m_attributes &= ~DontDelete; - else - m_attributes |= DontDelete; - m_seenAttributes |= ConfigurablePresent; -} - -void PropertyDescriptor::setSetter(JSValue setter) -{ - m_setter = setter; - m_attributes |= Setter; - m_attributes &= ~ReadOnly; -} - -void PropertyDescriptor::setGetter(JSValue getter) -{ - m_getter = getter; - m_attributes |= Getter; - m_attributes &= ~ReadOnly; -} - -bool PropertyDescriptor::equalTo(ExecState* exec, const PropertyDescriptor& other) const -{ - if (!other.m_value == m_value || - !other.m_getter == m_getter || - !other.m_setter == m_setter) - return false; - return (!m_value || JSValue::strictEqual(exec, other.m_value, m_value)) && - (!m_getter || JSValue::strictEqual(exec, other.m_getter, m_getter)) && - (!m_setter || JSValue::strictEqual(exec, other.m_setter, m_setter)) && - attributesEqual(other); -} - -bool PropertyDescriptor::attributesEqual(const PropertyDescriptor& other) const -{ - unsigned mismatch = other.m_attributes ^ m_attributes; - unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; - if (sharedSeen & WritablePresent && mismatch & ReadOnly) - return false; - if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) - return false; - if (sharedSeen & EnumerablePresent && mismatch & DontEnum) - return false; - return true; -} - -unsigned PropertyDescriptor::attributesWithOverride(const PropertyDescriptor& other) const -{ - unsigned mismatch = other.m_attributes ^ m_attributes; - unsigned sharedSeen = other.m_seenAttributes & m_seenAttributes; - unsigned newAttributes = m_attributes & defaultAttributes; - if (sharedSeen & WritablePresent && mismatch & ReadOnly) - newAttributes ^= ReadOnly; - if (sharedSeen & ConfigurablePresent && mismatch & DontDelete) - newAttributes ^= DontDelete; - if (sharedSeen & EnumerablePresent && mismatch & DontEnum) - newAttributes ^= DontEnum; - return newAttributes; -} - -} diff --git a/JavaScriptCore/runtime/PropertyDescriptor.h b/JavaScriptCore/runtime/PropertyDescriptor.h deleted file mode 100644 index ff9f160..0000000 --- a/JavaScriptCore/runtime/PropertyDescriptor.h +++ /dev/null @@ -1,80 +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 PropertyDescriptor_h -#define PropertyDescriptor_h - -#include "JSValue.h" - -namespace JSC { - class PropertyDescriptor { - public: - PropertyDescriptor() - : m_attributes(defaultAttributes) - , m_seenAttributes(0) - { - } - bool writable() const; - bool enumerable() const; - bool configurable() const; - bool isDataDescriptor() const; - bool isGenericDescriptor() const; - bool isAccessorDescriptor() const; - unsigned attributes() const { return m_attributes; } - JSValue value() const { return m_value; } - JSValue getter() const; - JSValue setter() const; - void setUndefined(); - void setDescriptor(JSValue value, unsigned attributes); - void setAccessorDescriptor(JSValue getter, JSValue setter, unsigned attributes); - void setWritable(bool); - void setEnumerable(bool); - void setConfigurable(bool); - void setValue(JSValue value) { m_value = value; } - void setSetter(JSValue); - void setGetter(JSValue); - bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); } - bool writablePresent() const { return m_seenAttributes & WritablePresent; } - bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; } - bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; } - bool setterPresent() const { return m_setter; } - bool getterPresent() const { return m_getter; } - bool equalTo(ExecState* exec, const PropertyDescriptor& other) const; - bool attributesEqual(const PropertyDescriptor& other) const; - unsigned attributesWithOverride(const PropertyDescriptor& other) const; - private: - static unsigned defaultAttributes; - bool operator==(const PropertyDescriptor&){ return false; } - enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4}; - // May be a getter/setter - JSValue m_value; - JSValue m_getter; - JSValue m_setter; - unsigned m_attributes; - unsigned m_seenAttributes; - }; -} - -#endif diff --git a/JavaScriptCore/runtime/PropertyMapHashTable.h b/JavaScriptCore/runtime/PropertyMapHashTable.h deleted file mode 100644 index bd452b6..0000000 --- a/JavaScriptCore/runtime/PropertyMapHashTable.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef PropertyMapHashTable_h -#define PropertyMapHashTable_h - -#include "UString.h" -#include <wtf/Vector.h> - -namespace JSC { - - struct PropertyMapEntry { - StringImpl* key; - unsigned offset; - unsigned attributes; - JSCell* specificValue; - unsigned index; - - PropertyMapEntry(StringImpl* key, unsigned attributes, JSCell* specificValue) - : key(key) - , offset(0) - , attributes(attributes) - , specificValue(specificValue) - , index(0) - { - } - - PropertyMapEntry(StringImpl* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index) - : key(key) - , offset(offset) - , attributes(attributes) - , specificValue(specificValue) - , index(index) - { - } - }; - - // lastIndexUsed is an ever-increasing index used to identify the order items - // were inserted into the property map. It's required that getEnumerablePropertyNames - // return the properties in the order they were added for compatibility with other - // browsers' JavaScript implementations. - struct PropertyMapHashTable { - unsigned sizeMask; - unsigned size; - unsigned keyCount; - unsigned deletedSentinelCount; - unsigned lastIndexUsed; - Vector<unsigned>* deletedOffsets; - unsigned entryIndices[1]; - - PropertyMapEntry* entries() - { - // The entries vector comes after the indices vector. - // The 0th item in the entries vector is not really used; it has to - // have a 0 in its key to allow the hash table lookup to handle deleted - // sentinels without any special-case code, but the other fields are unused. - return reinterpret_cast<PropertyMapEntry*>(&entryIndices[size]); - } - - static size_t allocationSize(unsigned size) - { - // We never let a hash table get more than half full, - // So the number of indices we need is the size of the hash table. - // But the number of entries is half that (plus one for the deleted sentinel). - return sizeof(PropertyMapHashTable) - + (size - 1) * sizeof(unsigned) - + (1 + size / 2) * sizeof(PropertyMapEntry); - } - }; - -} // namespace JSC - -#endif // PropertyMapHashTable_h diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp deleted file mode 100644 index afb41be..0000000 --- a/JavaScriptCore/runtime/PropertyNameArray.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "PropertyNameArray.h" - -#include "Structure.h" -#include "StructureChain.h" - -namespace JSC { - -static const size_t setThreshold = 20; - -void PropertyNameArray::add(StringImpl* identifier) -{ - ASSERT(!identifier || identifier == StringImpl::empty() || identifier->isIdentifier()); - - size_t size = m_data->propertyNameVector().size(); - if (size < setThreshold) { - for (size_t i = 0; i < size; ++i) { - if (identifier == m_data->propertyNameVector()[i].impl()) - return; - } - } else { - if (m_set.isEmpty()) { - for (size_t i = 0; i < size; ++i) - m_set.add(m_data->propertyNameVector()[i].impl()); - } - if (!m_set.add(identifier).second) - return; - } - - addKnownUnique(identifier); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/PropertyNameArray.h b/JavaScriptCore/runtime/PropertyNameArray.h deleted file mode 100644 index 0da930f..0000000 --- a/JavaScriptCore/runtime/PropertyNameArray.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef PropertyNameArray_h -#define PropertyNameArray_h - -#include "CallFrame.h" -#include "Identifier.h" -#include <wtf/HashSet.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/Vector.h> - -namespace JSC { - - class Structure; - class StructureChain; - - // FIXME: Rename to PropertyNameArray. - class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> { - public: - typedef Vector<Identifier, 20> PropertyNameVector; - - static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); } - - PropertyNameVector& propertyNameVector() { return m_propertyNameVector; } - - private: - PropertyNameArrayData() - { - } - - PropertyNameVector m_propertyNameVector; - }; - - // FIXME: Rename to PropertyNameArrayBuilder. - class PropertyNameArray { - public: - PropertyNameArray(JSGlobalData* globalData) - : m_data(PropertyNameArrayData::create()) - , m_globalData(globalData) - , m_shouldCache(true) - { - } - - PropertyNameArray(ExecState* exec) - : m_data(PropertyNameArrayData::create()) - , m_globalData(&exec->globalData()) - , m_shouldCache(true) - { - } - - JSGlobalData* globalData() { return m_globalData; } - - void add(const Identifier& identifier) { add(identifier.impl()); } - void add(StringImpl*); - void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); } - - Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; } - const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; } - - void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; } - PropertyNameArrayData* data() { return m_data.get(); } - PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); } - - // FIXME: Remove these functions. - typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator; - size_t size() const { return m_data->propertyNameVector().size(); } - const_iterator begin() const { return m_data->propertyNameVector().begin(); } - const_iterator end() const { return m_data->propertyNameVector().end(); } - - private: - typedef HashSet<StringImpl*, PtrHash<StringImpl*> > IdentifierSet; - - RefPtr<PropertyNameArrayData> m_data; - IdentifierSet m_set; - JSGlobalData* m_globalData; - bool m_shouldCache; - }; - -} // namespace JSC - -#endif // PropertyNameArray_h diff --git a/JavaScriptCore/runtime/PropertySlot.cpp b/JavaScriptCore/runtime/PropertySlot.cpp deleted file mode 100644 index fd16c0c..0000000 --- a/JavaScriptCore/runtime/PropertySlot.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2005, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "PropertySlot.h" - -#include "JSFunction.h" -#include "JSGlobalObject.h" - -namespace JSC { - -JSValue PropertySlot::functionGetter(ExecState* exec) const -{ - // Prevent getter functions from observing execution if an exception is pending. - if (exec->hadException()) - return exec->exception(); - - CallData callData; - CallType callType = m_data.getterFunc->getCallData(callData); - return call(exec, m_data.getterFunc, callType, callData, thisValue(), exec->emptyList()); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/PropertySlot.h b/JavaScriptCore/runtime/PropertySlot.h deleted file mode 100644 index de9ddc9..0000000 --- a/JavaScriptCore/runtime/PropertySlot.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef PropertySlot_h -#define PropertySlot_h - -#include "Identifier.h" -#include "JSValue.h" -#include "Register.h" -#include <wtf/Assertions.h> -#include <wtf/NotFound.h> - -namespace JSC { - - class ExecState; - class JSObject; - -#define JSC_VALUE_SLOT_MARKER 0 -#define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1) -#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2) -#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3) - - class PropertySlot { - public: - enum CachedPropertyType { - Uncacheable, - Getter, - Custom, - Value - }; - - PropertySlot() - : m_cachedPropertyType(Uncacheable) - { - clearBase(); - clearOffset(); - clearValue(); - } - - explicit PropertySlot(const JSValue base) - : m_slotBase(base) - , m_cachedPropertyType(Uncacheable) - { - clearOffset(); - clearValue(); - } - - typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, const Identifier&); - typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned); - - 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(); - if (m_getValue == INDEX_GETTER_MARKER) - return m_getIndexValue(exec, slotBase(), index()); - if (m_getValue == GETTER_FUNCTION_MARKER) - return functionGetter(exec); - return m_getValue(exec, slotBase(), propertyName); - } - - 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(); - if (m_getValue == INDEX_GETTER_MARKER) - return m_getIndexValue(exec, m_slotBase, m_data.index); - if (m_getValue == GETTER_FUNCTION_MARKER) - return functionGetter(exec); - return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName)); - } - - CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; } - bool isCacheable() const { return m_cachedPropertyType != Uncacheable; } - bool isCacheableValue() const { return m_cachedPropertyType == Value; } - size_t cachedOffset() const - { - ASSERT(isCacheable()); - return m_offset; - } - - void setValueSlot(JSValue* valueSlot) - { - ASSERT(valueSlot); - clearBase(); - clearOffset(); - m_getValue = JSC_VALUE_SLOT_MARKER; - m_data.valueSlot = valueSlot; - } - - void setValueSlot(JSValue slotBase, JSValue* valueSlot) - { - ASSERT(valueSlot); - m_getValue = JSC_VALUE_SLOT_MARKER; - m_slotBase = slotBase; - m_data.valueSlot = valueSlot; - } - - void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset) - { - ASSERT(valueSlot); - m_getValue = JSC_VALUE_SLOT_MARKER; - m_slotBase = slotBase; - m_data.valueSlot = valueSlot; - m_offset = offset; - m_cachedPropertyType = Value; - } - - void setValue(JSValue value) - { - ASSERT(value); - clearBase(); - clearOffset(); - m_getValue = JSC_VALUE_SLOT_MARKER; - m_value = value; - m_data.valueSlot = &m_value; - } - - void setRegisterSlot(Register* registerSlot) - { - ASSERT(registerSlot); - clearBase(); - clearOffset(); - m_getValue = JSC_REGISTER_SLOT_MARKER; - m_data.registerSlot = registerSlot; - } - - void setCustom(JSValue slotBase, GetValueFunc getValue) - { - ASSERT(slotBase); - ASSERT(getValue); - m_getValue = getValue; - m_getIndexValue = 0; - m_slotBase = slotBase; - } - - void setCacheableCustom(JSValue slotBase, GetValueFunc getValue) - { - ASSERT(slotBase); - ASSERT(getValue); - m_getValue = getValue; - m_getIndexValue = 0; - m_slotBase = slotBase; - m_cachedPropertyType = Custom; - } - - void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue) - { - ASSERT(slotBase); - ASSERT(getIndexValue); - m_getValue = INDEX_GETTER_MARKER; - m_getIndexValue = getIndexValue; - m_slotBase = slotBase; - m_data.index = index; - } - - void setGetterSlot(JSObject* getterFunc) - { - ASSERT(getterFunc); - m_thisValue = m_slotBase; - m_getValue = GETTER_FUNCTION_MARKER; - m_data.getterFunc = getterFunc; - } - - void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset) - { - ASSERT(getterFunc); - m_getValue = GETTER_FUNCTION_MARKER; - m_thisValue = m_slotBase; - m_slotBase = slotBase; - m_data.getterFunc = getterFunc; - m_offset = offset; - m_cachedPropertyType = Getter; - } - - void setUndefined() - { - setValue(jsUndefined()); - } - - JSValue slotBase() const - { - return m_slotBase; - } - - void setBase(JSValue base) - { - ASSERT(m_slotBase); - ASSERT(base); - m_slotBase = base; - } - - void clearBase() - { -#ifndef NDEBUG - m_slotBase = JSValue(); -#endif - } - - void clearValue() - { -#ifndef NDEBUG - m_value = JSValue(); -#endif - } - - void clearOffset() - { - // Clear offset even in release builds, in case this PropertySlot has been used before. - // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.) - m_offset = 0; - m_cachedPropertyType = Uncacheable; - } - - unsigned index() const { return m_data.index; } - - JSValue thisValue() const { return m_thisValue; } - - GetValueFunc customGetter() const - { - ASSERT(m_cachedPropertyType == Custom); - return m_getValue; - } - private: - JSValue functionGetter(ExecState*) const; - - GetValueFunc m_getValue; - GetIndexValueFunc m_getIndexValue; - - JSValue m_slotBase; - union { - JSObject* getterFunc; - JSValue* valueSlot; - Register* registerSlot; - unsigned index; - } m_data; - - JSValue m_value; - JSValue m_thisValue; - - size_t m_offset; - CachedPropertyType m_cachedPropertyType; - }; - -} // namespace JSC - -#endif // PropertySlot_h diff --git a/JavaScriptCore/runtime/Protect.h b/JavaScriptCore/runtime/Protect.h deleted file mode 100644 index 06cf97f..0000000 --- a/JavaScriptCore/runtime/Protect.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - - -#ifndef Protect_h -#define Protect_h - -#include "Collector.h" -#include "JSValue.h" - -namespace JSC { - - inline void gcProtect(JSCell* val) - { - Heap::heap(val)->protect(val); - } - - inline void gcUnprotect(JSCell* val) - { - Heap::heap(val)->unprotect(val); - } - - inline void gcProtectNullTolerant(JSCell* val) - { - if (val) - gcProtect(val); - } - - inline void gcUnprotectNullTolerant(JSCell* val) - { - if (val) - gcUnprotect(val); - } - - inline void gcProtect(JSValue value) - { - if (value && value.isCell()) - gcProtect(value.asCell()); - } - - inline void gcUnprotect(JSValue value) - { - if (value && value.isCell()) - gcUnprotect(value.asCell()); - } - - // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation - // and the implicit conversion to raw pointer - template <class T> class ProtectedPtr { - public: - ProtectedPtr() : m_ptr(0) {} - ProtectedPtr(T* ptr); - ProtectedPtr(const ProtectedPtr&); - ~ProtectedPtr(); - - template <class U> ProtectedPtr(const ProtectedPtr<U>&); - - T* get() const { return m_ptr; } - operator T*() const { return m_ptr; } - operator JSValue() const { return JSValue(m_ptr); } - T* operator->() const { return m_ptr; } - - operator bool() const { return m_ptr; } - bool operator!() const { return !m_ptr; } - - ProtectedPtr& operator=(const ProtectedPtr&); - ProtectedPtr& operator=(T*); - - private: - T* m_ptr; - }; - - class ProtectedJSValue { - public: - ProtectedJSValue() {} - ProtectedJSValue(JSValue value); - ProtectedJSValue(const ProtectedJSValue&); - ~ProtectedJSValue(); - - template <class U> ProtectedJSValue(const ProtectedPtr<U>&); - - JSValue get() const { return m_value; } - operator JSValue() const { return m_value; } - JSValue operator->() const { return m_value; } - - operator bool() const { return m_value; } - bool operator!() const { return !m_value; } - - ProtectedJSValue& operator=(const ProtectedJSValue&); - ProtectedJSValue& operator=(JSValue); - - private: - JSValue m_value; - }; - - template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr) - : m_ptr(ptr) - { - gcProtectNullTolerant(m_ptr); - } - - template <class T> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o) - : m_ptr(o.get()) - { - gcProtectNullTolerant(m_ptr); - } - - template <class T> inline ProtectedPtr<T>::~ProtectedPtr() - { - gcUnprotectNullTolerant(m_ptr); - } - - template <class T> template <class U> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o) - : m_ptr(o.get()) - { - gcProtectNullTolerant(m_ptr); - } - - template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o) - { - T* optr = o.m_ptr; - gcProtectNullTolerant(optr); - gcUnprotectNullTolerant(m_ptr); - m_ptr = optr; - return *this; - } - - template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr) - { - gcProtectNullTolerant(optr); - gcUnprotectNullTolerant(m_ptr); - m_ptr = optr; - return *this; - } - - inline ProtectedJSValue::ProtectedJSValue(JSValue value) - : m_value(value) - { - gcProtect(m_value); - } - - inline ProtectedJSValue::ProtectedJSValue(const ProtectedJSValue& o) - : m_value(o.get()) - { - gcProtect(m_value); - } - - inline ProtectedJSValue::~ProtectedJSValue() - { - gcUnprotect(m_value); - } - - template <class U> ProtectedJSValue::ProtectedJSValue(const ProtectedPtr<U>& o) - : m_value(o.get()) - { - gcProtect(m_value); - } - - inline ProtectedJSValue& ProtectedJSValue::operator=(const ProtectedJSValue& o) - { - JSValue ovalue = o.m_value; - gcProtect(ovalue); - gcUnprotect(m_value); - m_value = ovalue; - return *this; - } - - inline ProtectedJSValue& ProtectedJSValue::operator=(JSValue ovalue) - { - gcProtect(ovalue); - gcUnprotect(m_value); - m_value = ovalue; - return *this; - } - - template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); } - template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; } - template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); } - - template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); } - template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; } - template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); } - - inline bool operator==(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() == b.get(); } - inline bool operator==(const ProtectedJSValue& a, const JSValue b) { return a.get() == b; } - template <class T> inline bool operator==(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() == JSValue(b.get()); } - inline bool operator==(const JSValue a, const ProtectedJSValue& b) { return a == b.get(); } - template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) == b.get(); } - - inline bool operator!=(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() != b.get(); } - inline bool operator!=(const ProtectedJSValue& a, const JSValue b) { return a.get() != b; } - template <class T> inline bool operator!=(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() != JSValue(b.get()); } - inline bool operator!=(const JSValue a, const ProtectedJSValue& b) { return a != b.get(); } - template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) != b.get(); } - -} // namespace JSC - -#endif // Protect_h diff --git a/JavaScriptCore/runtime/PrototypeFunction.cpp b/JavaScriptCore/runtime/PrototypeFunction.cpp deleted file mode 100644 index 3529080..0000000 --- a/JavaScriptCore/runtime/PrototypeFunction.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "PrototypeFunction.h" - -#include "JSGlobalObject.h" -#include <wtf/Assertions.h> - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(PrototypeFunction); - -PrototypeFunction::PrototypeFunction(ExecState* exec, JSGlobalObject* globalObject, int length, const Identifier& name, NativeFunction function) - : InternalFunction(&exec->globalData(), globalObject, exec->lexicalGlobalObject()->prototypeFunctionStructure(), name) - , m_function(function) -{ - ASSERT_ARG(function, function); - putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); -} - -PrototypeFunction::PrototypeFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function) - : InternalFunction(&exec->globalData(), globalObject, prototypeFunctionStructure, name) - , m_function(function) -{ - ASSERT_ARG(function, function); - putDirect(exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); -} - -CallType PrototypeFunction::getCallData(CallData& callData) -{ - callData.native.function = m_function; - return CallTypeHost; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/PrototypeFunction.h b/JavaScriptCore/runtime/PrototypeFunction.h deleted file mode 100644 index 6ca2342..0000000 --- a/JavaScriptCore/runtime/PrototypeFunction.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef PrototypeFunction_h -#define PrototypeFunction_h - -#include "InternalFunction.h" -#include "CallData.h" - -namespace JSC { - - class PrototypeFunction : public InternalFunction { - public: - PrototypeFunction(ExecState*, JSGlobalObject*, int length, const Identifier&, NativeFunction); - PrototypeFunction(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction); - - private: - virtual CallType getCallData(CallData&); - - const NativeFunction m_function; - }; - -} // namespace JSC - -#endif // PrototypeFunction_h diff --git a/JavaScriptCore/runtime/PutPropertySlot.h b/JavaScriptCore/runtime/PutPropertySlot.h deleted file mode 100644 index 4b0b394..0000000 --- a/JavaScriptCore/runtime/PutPropertySlot.h +++ /dev/null @@ -1,80 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PutPropertySlot_h -#define PutPropertySlot_h - -#include <wtf/Assertions.h> - -namespace JSC { - - class JSObject; - class JSFunction; - - class PutPropertySlot { - public: - enum Type { Uncachable, ExistingProperty, NewProperty }; - - PutPropertySlot(bool isStrictMode = false) - : m_type(Uncachable) - , m_base(0) - , m_isStrictMode(isStrictMode) - { - } - - void setExistingProperty(JSObject* base, size_t offset) - { - m_type = ExistingProperty; - m_base = base; - m_offset = offset; - } - - void setNewProperty(JSObject* base, size_t offset) - { - m_type = NewProperty; - m_base = base; - m_offset = offset; - } - - Type type() const { return m_type; } - JSObject* base() const { return m_base; } - - bool isStrictMode() const { return m_isStrictMode; } - bool isCacheable() const { return m_type != Uncachable; } - size_t cachedOffset() const { - ASSERT(isCacheable()); - return m_offset; - } - private: - Type m_type; - JSObject* m_base; - size_t m_offset; - bool m_isStrictMode; - }; - -} // namespace JSC - -#endif // PutPropertySlot_h diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp deleted file mode 100644 index 9b2e3f3..0000000 --- a/JavaScriptCore/runtime/RegExp.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org) - * Copyright (c) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Torch Mobile, Inc. - * Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "RegExp.h" -#include "Lexer.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wtf/Assertions.h> -#include <wtf/OwnArrayPtr.h> - -#include "yarr/RegexCompiler.h" -#include "yarr/RegexJIT.h" -#include "yarr/RegexInterpreter.h" -#include "yarr/RegexPattern.h" - -namespace JSC { - -struct RegExpRepresentation { -#if ENABLE(YARR_JIT) - Yarr::RegexCodeBlock m_regExpJITCode; -#endif - OwnPtr<Yarr::BytecodePattern> m_regExpBytecode; -}; - -inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, const UString& flags) - : m_patternString(patternString) - , m_flagBits(0) - , m_constructionError(0) - , m_numSubpatterns(0) -#if ENABLE(REGEXP_TRACING) - , m_rtMatchCallCount(0) - , m_rtMatchFoundCount(0) -#endif - , m_representation(adoptPtr(new RegExpRepresentation)) -{ - // NOTE: The global flag is handled on a case-by-case basis by functions like - // String::match and RegExpObject::match. - if (!flags.isNull()) { - if (flags.find('g') != notFound) - m_flagBits |= Global; - if (flags.find('i') != notFound) - m_flagBits |= IgnoreCase; - if (flags.find('m') != notFound) - m_flagBits |= Multiline; - } - - m_state = compile(globalData); -} - -RegExp::~RegExp() -{ -} - -PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, const UString& flags) -{ - RefPtr<RegExp> res = adoptRef(new RegExp(globalData, patternString, flags)); -#if ENABLE(REGEXP_TRACING) - globalData->addRegExpToTrace(res); -#endif - return res.release(); -} - -RegExp::RegExpState RegExp::compile(JSGlobalData* globalData) -{ - Yarr::RegexPattern pattern(ignoreCase(), multiline()); - - if ((m_constructionError = Yarr::compileRegex(m_patternString, pattern))) - return ParseError; - - m_numSubpatterns = pattern.m_numSubpatterns; - -#if ENABLE(YARR_JIT) - if (!pattern.m_containsBackreferences && globalData->canUseJIT()) { - Yarr::jitCompileRegex(pattern, globalData, m_representation->m_regExpJITCode); - if (!m_representation->m_regExpJITCode.isFallBack()) - return JITCode; - } -#endif - - m_representation->m_regExpBytecode = Yarr::byteCompileRegex(pattern, &globalData->m_regexAllocator); - return ByteCode; -} - -int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) -{ - if (startOffset < 0) - startOffset = 0; - -#if ENABLE(REGEXP_TRACING) - m_rtMatchCallCount++; -#endif - - if (static_cast<unsigned>(startOffset) > s.length() || s.isNull()) - return -1; - - if (m_state != ParseError) { - int offsetVectorSize = (m_numSubpatterns + 1) * 2; - int* offsetVector; - Vector<int, 32> nonReturnedOvector; - if (ovector) { - ovector->resize(offsetVectorSize); - offsetVector = ovector->data(); - } else { - nonReturnedOvector.resize(offsetVectorSize); - offsetVector = nonReturnedOvector.data(); - } - - ASSERT(offsetVector); - // Initialize offsetVector with the return value (index 0) and the - // first subpattern start indicies (even index values) set to -1. - // No need to init the subpattern end indicies. - for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++) - offsetVector[j] = -1; - - int result; -#if ENABLE(YARR_JIT) - if (m_state == JITCode) - result = Yarr::executeRegex(m_representation->m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector); - else -#endif - result = Yarr::interpretRegex(m_representation->m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector); - - ASSERT(result >= -1);; - -#if ENABLE(REGEXP_TRACING) - if (result != -1) - m_rtMatchFoundCount++; -#endif - - return result; - } - - return -1; -} - -#if ENABLE(REGEXP_TRACING) - void RegExp::printTraceData() - { - char formattedPattern[41]; - char rawPattern[41]; - - strncpy(rawPattern, m_pattern.utf8().data(), 40); - rawPattern[40]= '\0'; - - int pattLen = strlen(rawPattern); - - snprintf(formattedPattern, 41, (pattLen <= 38) ? "/%.38s/" : "/%.36s...", rawPattern); - -#if ENABLE(YARR_JIT) - Yarr::RegexCodeBlock& codeBlock = m_representation->m_regExpJITCode; - - char jitAddr[20]; - if (m_state == JITCode) - sprintf(jitAddr, "fallback"); - else - sprintf(jitAddr, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.getAddr())); -#else - const char* jitAddr = "JIT Off"; -#endif - - printf("%-40.40s %16.16s %10d %10d\n", formattedPattern, jitAddr, m_rtMatchCallCount, m_rtMatchFoundCount); - } -#endif - -} // namespace JSC diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h deleted file mode 100644 index 8f33f57..0000000 --- a/JavaScriptCore/runtime/RegExp.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef RegExp_h -#define RegExp_h - -#include "UString.h" -#include "ExecutableAllocator.h" -#include <wtf/Forward.h> -#include <wtf/RefCounted.h> - -namespace JSC { - - struct RegExpRepresentation; - class JSGlobalData; - - class RegExp : public RefCounted<RegExp> { - public: - static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags); - ~RegExp(); - - bool global() const { return m_flagBits & Global; } - bool ignoreCase() const { return m_flagBits & IgnoreCase; } - bool multiline() const { return m_flagBits & Multiline; } - - const UString& pattern() const { return m_patternString; } - - bool isValid() const { return !m_constructionError; } - const char* errorMessage() const { return m_constructionError; } - - int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0); - unsigned numSubpatterns() const { return m_numSubpatterns; } - -#if ENABLE(REGEXP_TRACING) - void printTraceData(); -#endif - - private: - RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags); - - enum RegExpState { - ParseError, - JITCode, - ByteCode - } m_state; - - RegExpState compile(JSGlobalData*); - - enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 }; - UString m_patternString; - int m_flagBits; - const char* m_constructionError; - unsigned m_numSubpatterns; -#if ENABLE(REGEXP_TRACING) - unsigned m_rtMatchCallCount; - unsigned m_rtMatchFoundCount; -#endif - - OwnPtr<RegExpRepresentation> m_representation; - }; - -} // namespace JSC - -#endif // RegExp_h diff --git a/JavaScriptCore/runtime/RegExpCache.cpp b/JavaScriptCore/runtime/RegExpCache.cpp deleted file mode 100644 index d101758..0000000 --- a/JavaScriptCore/runtime/RegExpCache.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2010 University of Szeged - * Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu) - * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED 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 "RegExpCache.h" - -namespace JSC { - -PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags) -{ - if (patternString.length() < maxCacheablePatternLength) { - pair<RegExpCacheMap::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0); - if (!result.second) - return result.first->second; - else - return create(patternString, flags, result.first); - } - return create(patternString, flags, m_cacheMap.end()); -} - -PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator) -{ - RefPtr<RegExp> regExp = RegExp::create(m_globalData, patternString, flags); - - if (patternString.length() >= maxCacheablePatternLength) - return regExp; - - RegExpKey key = RegExpKey(flags, patternString); - iterator->first = key; - iterator->second = regExp; - - ++m_nextKeyToEvict; - if (m_nextKeyToEvict == maxCacheableEntries) { - m_nextKeyToEvict = 0; - m_isFull = true; - } - if (m_isFull) - m_cacheMap.remove(RegExpKey(patternKeyArray[m_nextKeyToEvict].flagsValue, patternKeyArray[m_nextKeyToEvict].pattern)); - - patternKeyArray[m_nextKeyToEvict].flagsValue = key.flagsValue; - patternKeyArray[m_nextKeyToEvict].pattern = patternString.impl(); - return regExp; -} - -RegExpCache::RegExpCache(JSGlobalData* globalData) - : m_globalData(globalData) - , m_nextKeyToEvict(-1) - , m_isFull(false) -{ -} - -} diff --git a/JavaScriptCore/runtime/RegExpCache.h b/JavaScriptCore/runtime/RegExpCache.h deleted file mode 100644 index b5b637f..0000000 --- a/JavaScriptCore/runtime/RegExpCache.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2010 University of Szeged - * Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu) - * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED 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 "RegExp.h" -#include "RegExpKey.h" -#include "UString.h" -#include <wtf/FixedArray.h> -#include <wtf/HashMap.h> - -#ifndef RegExpCache_h -#define RegExpCache_h - -namespace JSC { - -class RegExpCache { - -typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap; - -public: - PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, const UString& flags); - PassRefPtr<RegExp> create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator); - RegExpCache(JSGlobalData* globalData); - -private: - static const unsigned maxCacheablePatternLength = 256; - -#if PLATFORM(IOS) - // The RegExpCache can currently hold onto multiple Mb of memory; - // as a short-term fix some embedded platforms may wish to reduce the cache size. - static const int maxCacheableEntries = 32; -#else - static const int maxCacheableEntries = 256; -#endif - - FixedArray<RegExpKey, maxCacheableEntries> patternKeyArray; - RegExpCacheMap m_cacheMap; - JSGlobalData* m_globalData; - int m_nextKeyToEvict; - bool m_isFull; -}; - -} // namespace JSC - -#endif // RegExpCache_h diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp deleted file mode 100644 index 21ca170..0000000 --- a/JavaScriptCore/runtime/RegExpConstructor.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. - * Copyright (C) 2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "RegExpConstructor.h" - -#include "ArrayPrototype.h" -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSArray.h" -#include "JSFunction.h" -#include "JSString.h" -#include "Lookup.h" -#include "ObjectPrototype.h" -#include "RegExpMatchesArray.h" -#include "RegExpObject.h" -#include "RegExpPrototype.h" -#include "RegExp.h" -#include "RegExpCache.h" -#include "UStringConcatenate.h" -#include <wtf/PassOwnPtr.h> - -namespace JSC { - -static JSValue regExpConstructorInput(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorMultiline(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorLastMatch(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorLastParen(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorLeftContext(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorRightContext(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar1(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar2(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar3(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar4(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar5(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar6(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar7(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar8(ExecState*, JSValue, const Identifier&); -static JSValue regExpConstructorDollar9(ExecState*, JSValue, const Identifier&); - -static void setRegExpConstructorInput(ExecState*, JSObject*, JSValue); -static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue); - -} // namespace JSC - -#include "RegExpConstructor.lut.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(RegExpConstructor); - -const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info, 0, ExecState::regExpConstructorTable }; - -/* Source for RegExpConstructor.lut.h -@begin regExpConstructorTable - input regExpConstructorInput None - $_ regExpConstructorInput DontEnum - multiline regExpConstructorMultiline None - $* regExpConstructorMultiline DontEnum - lastMatch regExpConstructorLastMatch DontDelete|ReadOnly - $& regExpConstructorLastMatch DontDelete|ReadOnly|DontEnum - lastParen regExpConstructorLastParen DontDelete|ReadOnly - $+ regExpConstructorLastParen DontDelete|ReadOnly|DontEnum - leftContext regExpConstructorLeftContext DontDelete|ReadOnly - $` regExpConstructorLeftContext DontDelete|ReadOnly|DontEnum - rightContext regExpConstructorRightContext DontDelete|ReadOnly - $' regExpConstructorRightContext DontDelete|ReadOnly|DontEnum - $1 regExpConstructorDollar1 DontDelete|ReadOnly - $2 regExpConstructorDollar2 DontDelete|ReadOnly - $3 regExpConstructorDollar3 DontDelete|ReadOnly - $4 regExpConstructorDollar4 DontDelete|ReadOnly - $5 regExpConstructorDollar5 DontDelete|ReadOnly - $6 regExpConstructorDollar6 DontDelete|ReadOnly - $7 regExpConstructorDollar7 DontDelete|ReadOnly - $8 regExpConstructorDollar8 DontDelete|ReadOnly - $9 regExpConstructorDollar9 DontDelete|ReadOnly -@end -*/ - -RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, "RegExp")) - , d(adoptPtr(new RegExpConstructorPrivate)) -{ - // ECMA 15.10.5.1 RegExp.prototype - putDirectWithoutTransition(exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly); - - // no. of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum); -} - -RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data) - : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1, CreateInitialized) -{ - RegExpConstructorPrivate* d = new RegExpConstructorPrivate; - d->input = data->lastInput; - d->lastInput = data->lastInput; - d->lastNumSubPatterns = data->lastNumSubPatterns; - unsigned offsetVectorSize = (data->lastNumSubPatterns + 1) * 2; // only copying the result part of the vector - d->lastOvector().resize(offsetVectorSize); - memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int)); - // d->multiline is not needed, and remains uninitialized - - setSubclassData(d); -} - -RegExpMatchesArray::~RegExpMatchesArray() -{ - delete static_cast<RegExpConstructorPrivate*>(subclassData()); -} - -void RegExpMatchesArray::fillArrayInstance(ExecState* exec) -{ - RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(subclassData()); - ASSERT(d); - - unsigned lastNumSubpatterns = d->lastNumSubPatterns; - - for (unsigned i = 0; i <= lastNumSubpatterns; ++i) { - int start = d->lastOvector()[2 * i]; - if (start >= 0) - JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start)); - else - JSArray::put(exec, i, jsUndefined()); - } - - PutPropertySlot slot; - JSArray::put(exec, exec->propertyNames().index, jsNumber(d->lastOvector()[0]), slot); - JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot); - - delete d; - setSubclassData(0); -} - -JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const -{ - return new (exec) RegExpMatchesArray(exec, d.get()); -} - -JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) const -{ - if (!d->lastOvector().isEmpty() && i <= d->lastNumSubPatterns) { - int start = d->lastOvector()[2 * i]; - if (start >= 0) - return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start); - } - return jsEmptyString(exec); -} - -JSValue RegExpConstructor::getLastParen(ExecState* exec) const -{ - unsigned i = d->lastNumSubPatterns; - if (i > 0) { - ASSERT(!d->lastOvector().isEmpty()); - int start = d->lastOvector()[2 * i]; - if (start >= 0) - return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start); - } - return jsEmptyString(exec); -} - -JSValue RegExpConstructor::getLeftContext(ExecState* exec) const -{ - if (!d->lastOvector().isEmpty()) - return jsSubstring(exec, d->lastInput, 0, d->lastOvector()[0]); - return jsEmptyString(exec); -} - -JSValue RegExpConstructor::getRightContext(ExecState* exec) const -{ - if (!d->lastOvector().isEmpty()) - return jsSubstring(exec, d->lastInput, d->lastOvector()[1], d->lastInput.length() - d->lastOvector()[1]); - return jsEmptyString(exec); -} - -bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot); -} - -bool RegExpConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticValueDescriptor<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, descriptor); -} - -JSValue regExpConstructorDollar1(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 1); -} - -JSValue regExpConstructorDollar2(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 2); -} - -JSValue regExpConstructorDollar3(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 3); -} - -JSValue regExpConstructorDollar4(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 4); -} - -JSValue regExpConstructorDollar5(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 5); -} - -JSValue regExpConstructorDollar6(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 6); -} - -JSValue regExpConstructorDollar7(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 7); -} - -JSValue regExpConstructorDollar8(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 8); -} - -JSValue regExpConstructorDollar9(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 9); -} - -JSValue regExpConstructorInput(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return jsString(exec, asRegExpConstructor(slotBase)->input()); -} - -JSValue regExpConstructorMultiline(ExecState*, JSValue slotBase, const Identifier&) -{ - return jsBoolean(asRegExpConstructor(slotBase)->multiline()); -} - -JSValue regExpConstructorLastMatch(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getBackref(exec, 0); -} - -JSValue regExpConstructorLastParen(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getLastParen(exec); -} - -JSValue regExpConstructorLeftContext(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getLeftContext(exec); -} - -JSValue regExpConstructorRightContext(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return asRegExpConstructor(slotBase)->getRightContext(exec); -} - -void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this, slot); -} - -void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue value) -{ - asRegExpConstructor(baseObject)->setInput(value.toString(exec)); -} - -void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue value) -{ - asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec)); -} - -// ECMA 15.10.4 -JSObject* constructRegExp(ExecState* exec, const ArgList& args) -{ - JSValue arg0 = args.at(0); - JSValue arg1 = args.at(1); - - if (arg0.inherits(&RegExpObject::info)) { - if (!arg1.isUndefined()) - return throwError(exec, createTypeError(exec, "Cannot supply flags when constructing one RegExp from another.")); - return asObject(arg0); - } - - UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec); - UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec); - - RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags); - if (!regExp->isValid()) - return throwError(exec, createSyntaxError(exec, makeUString("Invalid regular expression: ", regExp->errorMessage()))); - return new (exec) RegExpObject(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp.release()); -} - -static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructRegExp(exec, args)); -} - -ConstructType RegExpConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithRegExpConstructor; - return ConstructTypeHost; -} - -// ECMA 15.10.3 -static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec) -{ - ArgList args(exec); - return JSValue::encode(constructRegExp(exec, args)); -} - -CallType RegExpConstructor::getCallData(CallData& callData) -{ - callData.native.function = callRegExpConstructor; - return CallTypeHost; -} - -void RegExpConstructor::setInput(const UString& input) -{ - d->input = input; -} - -const UString& RegExpConstructor::input() const -{ - // Can detect a distinct initial state that is invisible to JavaScript, by checking for null - // state (since jsString turns null strings to empty strings). - return d->input; -} - -void RegExpConstructor::setMultiline(bool multiline) -{ - d->multiline = multiline; -} - -bool RegExpConstructor::multiline() const -{ - return d->multiline; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/RegExpConstructor.h b/JavaScriptCore/runtime/RegExpConstructor.h deleted file mode 100644 index 58abde5..0000000 --- a/JavaScriptCore/runtime/RegExpConstructor.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef RegExpConstructor_h -#define RegExpConstructor_h - -#include "InternalFunction.h" -#include "RegExp.h" -#include <wtf/OwnPtr.h> - -namespace JSC { - - class RegExp; - class RegExpPrototype; - struct RegExpConstructorPrivate; - - struct RegExpConstructorPrivate : FastAllocBase { - // Global search cache / settings - RegExpConstructorPrivate() - : lastNumSubPatterns(0) - , multiline(false) - , lastOvectorIndex(0) - { - } - - const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; } - Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; } - Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; } - void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; } - - UString input; - UString lastInput; - Vector<int, 32> ovector[2]; - unsigned lastNumSubPatterns : 30; - bool multiline : 1; - unsigned lastOvectorIndex : 1; - }; - - class RegExpConstructor : public InternalFunction { - public: - RegExpConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, RegExpPrototype*); - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - static const ClassInfo info; - - void performMatch(RegExp*, const UString&, int startOffset, int& position, int& length, int** ovector = 0); - JSObject* arrayOfMatches(ExecState*) const; - - void setInput(const UString&); - const UString& input() const; - - void setMultiline(bool); - bool multiline() const; - - JSValue getBackref(ExecState*, unsigned) const; - JSValue getLastParen(ExecState*) const; - JSValue getLeftContext(ExecState*) const; - JSValue getRightContext(ExecState*) const; - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; - - private: - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - - virtual const ClassInfo* classInfo() const { return &info; } - - OwnPtr<RegExpConstructorPrivate> d; - }; - - RegExpConstructor* asRegExpConstructor(JSValue); - - JSObject* constructRegExp(ExecState*, const ArgList&); - - inline RegExpConstructor* asRegExpConstructor(JSValue value) - { - ASSERT(asObject(value)->inherits(&RegExpConstructor::info)); - return static_cast<RegExpConstructor*>(asObject(value)); - } - - /* - To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular - expression matching through the performMatch function. We use cached results to calculate, - e.g., RegExp.lastMatch and RegExp.leftParen. - */ - ALWAYS_INLINE void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector) - { - position = r->match(s, startOffset, &d->tempOvector()); - - if (ovector) - *ovector = d->tempOvector().data(); - - if (position != -1) { - ASSERT(!d->tempOvector().isEmpty()); - - length = d->tempOvector()[1] - d->tempOvector()[0]; - - d->input = s; - d->lastInput = s; - d->changeLastOvector(); - d->lastNumSubPatterns = r->numSubpatterns(); - } - } - -} // namespace JSC - -#endif // RegExpConstructor_h diff --git a/JavaScriptCore/runtime/RegExpKey.h b/JavaScriptCore/runtime/RegExpKey.h deleted file mode 100644 index cd1368d..0000000 --- a/JavaScriptCore/runtime/RegExpKey.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2010 University of Szeged - * Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu) - * 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED 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 "UString.h" -#include <wtf/text/StringHash.h> - -#ifndef RegExpKey_h -#define RegExpKey_h - -namespace JSC { - -struct RegExpKey { - int flagsValue; - RefPtr<StringImpl> pattern; - - RegExpKey() - : flagsValue(0) - { - } - - RegExpKey(int flags) - : flagsValue(flags) - { - } - - RegExpKey(int flags, const UString& pattern) - : flagsValue(flags) - , pattern(pattern.impl()) - { - } - - RegExpKey(int flags, const PassRefPtr<StringImpl> pattern) - : flagsValue(flags) - , pattern(pattern) - { - } - - RegExpKey(int flags, const RefPtr<StringImpl>& pattern) - : flagsValue(flags) - , pattern(pattern) - { - } - - RegExpKey(const UString& flags, const UString& pattern) - : pattern(pattern.impl()) - { - flagsValue = getFlagsValue(flags); - } - - int getFlagsValue(const UString flags) - { - flagsValue = 0; - if (flags.find('g') != notFound) - flagsValue += 4; - if (flags.find('i') != notFound) - flagsValue += 2; - if (flags.find('m') != notFound) - flagsValue += 1; - return flagsValue; - } -}; - -inline bool operator==(const RegExpKey& a, const RegExpKey& b) -{ - if (a.flagsValue != b.flagsValue) - return false; - if (!a.pattern) - return !b.pattern; - if (!b.pattern) - return false; - return equal(a.pattern.get(), b.pattern.get()); -} - -} // namespace JSC - -namespace WTF { -template<typename T> struct DefaultHash; -template<typename T> struct RegExpHash; - -template<> struct RegExpHash<JSC::RegExpKey> { - static unsigned hash(const JSC::RegExpKey& key) { return key.pattern->hash(); } - static bool equal(const JSC::RegExpKey& a, const JSC::RegExpKey& b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = false; -}; - -template<> struct DefaultHash<JSC::RegExpKey> { - typedef RegExpHash<JSC::RegExpKey> Hash; -}; - -template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> { - static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = -1; } - static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == -1; } -}; -} // namespace WTF - -#endif // RegExpKey_h diff --git a/JavaScriptCore/runtime/RegExpMatchesArray.h b/JavaScriptCore/runtime/RegExpMatchesArray.h deleted file mode 100644 index b823621..0000000 --- a/JavaScriptCore/runtime/RegExpMatchesArray.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef RegExpMatchesArray_h -#define RegExpMatchesArray_h - -#include "JSArray.h" - -namespace JSC { - - class RegExpMatchesArray : public JSArray { - public: - RegExpMatchesArray(ExecState*, RegExpConstructorPrivate*); - virtual ~RegExpMatchesArray(); - - private: - virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) - { - if (subclassData()) - fillArrayInstance(exec); - return JSArray::getOwnPropertySlot(exec, propertyName, slot); - } - - virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) - { - if (subclassData()) - fillArrayInstance(exec); - return JSArray::getOwnPropertySlot(exec, propertyName, slot); - } - - virtual bool getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) - { - if (subclassData()) - fillArrayInstance(exec); - return JSArray::getOwnPropertyDescriptor(exec, propertyName, descriptor); - } - - virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot) - { - if (subclassData()) - fillArrayInstance(exec); - JSArray::put(exec, propertyName, v, slot); - } - - virtual void put(ExecState* exec, unsigned propertyName, JSValue v) - { - if (subclassData()) - fillArrayInstance(exec); - JSArray::put(exec, propertyName, v); - } - - virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName) - { - if (subclassData()) - fillArrayInstance(exec); - return JSArray::deleteProperty(exec, propertyName); - } - - virtual bool deleteProperty(ExecState* exec, unsigned propertyName) - { - if (subclassData()) - fillArrayInstance(exec); - return JSArray::deleteProperty(exec, propertyName); - } - - virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties) - { - if (subclassData()) - fillArrayInstance(exec); - JSArray::getOwnPropertyNames(exec, arr, mode); - } - - void fillArrayInstance(ExecState*); -}; - -} - -#endif // RegExpMatchesArray_h diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp deleted file mode 100644 index 7fda5b1..0000000 --- a/JavaScriptCore/runtime/RegExpObject.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "RegExpObject.h" - -#include "Error.h" -#include "ExceptionHelpers.h" -#include "JSArray.h" -#include "JSGlobalObject.h" -#include "JSString.h" -#include "Lookup.h" -#include "RegExpConstructor.h" -#include "RegExpPrototype.h" -#include "UStringConcatenate.h" -#include <wtf/PassOwnPtr.h> - -namespace JSC { - -static JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&); -static JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&); -static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&); -static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&); -static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&); -static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue); - -} // namespace JSC - -#include "RegExpObject.lut.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(RegExpObject); - -const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable }; - -/* Source for RegExpObject.lut.h -@begin regExpTable - global regExpObjectGlobal DontDelete|ReadOnly|DontEnum - ignoreCase regExpObjectIgnoreCase DontDelete|ReadOnly|DontEnum - multiline regExpObjectMultiline DontDelete|ReadOnly|DontEnum - source regExpObjectSource DontDelete|ReadOnly|DontEnum - lastIndex regExpObjectLastIndex DontDelete|DontEnum -@end -*/ - -RegExpObject::RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp) - : JSObjectWithGlobalObject(globalObject, structure) - , d(adoptPtr(new RegExpObjectData(regExp, 0))) -{ -} - -RegExpObject::~RegExpObject() -{ -} - -bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot); -} - -bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor); -} - -JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&) -{ - return jsBoolean(asRegExpObject(slotBase)->regExp()->global()); -} - -JSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&) -{ - return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase()); -} - -JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&) -{ - return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline()); -} - -JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&) -{ - return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern()); -} - -JSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&) -{ - return jsNumber(asRegExpObject(slotBase)->lastIndex()); -} - -void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot); -} - -void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value) -{ - asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec)); -} - -JSValue RegExpObject::test(ExecState* exec) -{ - return jsBoolean(match(exec)); -} - -JSValue RegExpObject::exec(ExecState* exec) -{ - if (match(exec)) - return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec); - return jsNull(); -} - -static EncodedJSValue JSC_HOST_CALL callRegExpObject(ExecState* exec) -{ - return JSValue::encode(asRegExpObject(exec->callee())->exec(exec)); -} - -CallType RegExpObject::getCallData(CallData& callData) -{ - callData.native.function = callRegExpObject; - return CallTypeHost; -} - -// Shared implementation used by test and exec. -bool RegExpObject::match(ExecState* exec) -{ - RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); - - UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec); - if (input.isNull()) { - throwError(exec, createError(exec, makeUString("No input to ", toString(exec), "."))); - return false; - } - - if (!regExp()->global()) { - int position; - int length; - regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length); - return position >= 0; - } - - if (d->lastIndex < 0 || d->lastIndex > input.length()) { - d->lastIndex = 0; - return false; - } - - int position; - int length = 0; - regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length); - if (position < 0) { - d->lastIndex = 0; - return false; - } - - d->lastIndex = position + length; - return true; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h deleted file mode 100644 index 19de929..0000000 --- a/JavaScriptCore/runtime/RegExpObject.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef RegExpObject_h -#define RegExpObject_h - -#include "JSObjectWithGlobalObject.h" -#include "RegExp.h" - -namespace JSC { - - class RegExpObject : public JSObjectWithGlobalObject { - public: - RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure>, NonNullPassRefPtr<RegExp>); - virtual ~RegExpObject(); - - void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; } - RegExp* regExp() const { return d->regExp.get(); } - - void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; } - double lastIndex() const { return d->lastIndex; } - - JSValue test(ExecState*); - JSValue exec(ExecState*); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); - - virtual const ClassInfo* classInfo() const { return &info; } - static JS_EXPORTDATA const ClassInfo info; - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObjectWithGlobalObject::StructureFlags; - - private: - bool match(ExecState*); - - virtual CallType getCallData(CallData&); - - struct RegExpObjectData : FastAllocBase { - RegExpObjectData(NonNullPassRefPtr<RegExp> regExp, double lastIndex) - : regExp(regExp) - , lastIndex(lastIndex) - { - } - - RefPtr<RegExp> regExp; - double lastIndex; - }; - - OwnPtr<RegExpObjectData> d; - }; - - RegExpObject* asRegExpObject(JSValue); - - inline RegExpObject* asRegExpObject(JSValue value) - { - ASSERT(asObject(value)->inherits(&RegExpObject::info)); - return static_cast<RegExpObject*>(asObject(value)); - } - -} // namespace JSC - -#endif // RegExpObject_h diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp deleted file mode 100644 index 0a4c8bf..0000000 --- a/JavaScriptCore/runtime/RegExpPrototype.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "RegExpPrototype.h" - -#include "ArrayPrototype.h" -#include "Error.h" -#include "JSArray.h" -#include "JSFunction.h" -#include "JSObject.h" -#include "JSString.h" -#include "JSStringBuilder.h" -#include "JSValue.h" -#include "ObjectPrototype.h" -#include "PrototypeFunction.h" -#include "RegExpObject.h" -#include "RegExp.h" -#include "RegExpCache.h" -#include "UStringConcatenate.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype); - -static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*); -static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*); -static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*); -static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*); - -// ECMA 15.10.5 - -RegExpPrototype::RegExpPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure) - : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", "")) -{ - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum); - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum); -} - -// ------------------------------ Functions --------------------------- - -EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&RegExpObject::info)) - return throwVMTypeError(exec); - return JSValue::encode(asRegExpObject(thisValue)->test(exec)); -} - -EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&RegExpObject::info)) - return throwVMTypeError(exec); - return JSValue::encode(asRegExpObject(thisValue)->exec(exec)); -} - -EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&RegExpObject::info)) - return throwVMTypeError(exec); - - RefPtr<RegExp> regExp; - JSValue arg0 = exec->argument(0); - JSValue arg1 = exec->argument(1); - - if (arg0.inherits(&RegExpObject::info)) { - if (!arg1.isUndefined()) - return throwVMError(exec, createTypeError(exec, "Cannot supply flags when constructing one RegExp from another.")); - regExp = asRegExpObject(arg0)->regExp(); - } else { - UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec); - UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec); - regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags); - } - - if (!regExp->isValid()) - return throwVMError(exec, createSyntaxError(exec, makeUString("Invalid regular expression: ", regExp->errorMessage()))); - - asRegExpObject(thisValue)->setRegExp(regExp.release()); - asRegExpObject(thisValue)->setLastIndex(0); - return JSValue::encode(jsUndefined()); -} - -EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (!thisValue.inherits(&RegExpObject::info)) { - if (thisValue.inherits(&RegExpPrototype::info)) - return JSValue::encode(jsNontrivialString(exec, "//")); - return throwVMTypeError(exec); - } - - char postfix[5] = { '/', 0, 0, 0, 0 }; - int index = 1; - if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec)) - postfix[index++] = 'g'; - if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec)) - postfix[index++] = 'i'; - if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec)) - postfix[index] = 'm'; - UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec); - // If source is empty, use "/(?:)/" to avoid colliding with comment syntax - return JSValue::encode(jsMakeNontrivialString(exec, "/", source.length() ? source : UString("(?:)"), postfix)); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/RegExpPrototype.h b/JavaScriptCore/runtime/RegExpPrototype.h deleted file mode 100644 index eb4ae00..0000000 --- a/JavaScriptCore/runtime/RegExpPrototype.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef RegExpPrototype_h -#define RegExpPrototype_h - -#include "RegExpObject.h" -#include "JSObject.h" - -namespace JSC { - - class RegExpPrototype : public RegExpObject { - public: - RegExpPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure); - }; - -} // namespace JSC - -#endif // RegExpPrototype_h diff --git a/JavaScriptCore/runtime/RopeImpl.cpp b/JavaScriptCore/runtime/RopeImpl.cpp deleted file mode 100644 index 09c24a9..0000000 --- a/JavaScriptCore/runtime/RopeImpl.cpp +++ /dev/null @@ -1,62 +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. - */ - -#include "config.h" -#include "RopeImpl.h" - -namespace JSC { - -void RopeImpl::derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue) -{ - unsigned fiberCount = this->fiberCount(); - for (unsigned i = 0; i < fiberCount; ++i) { - Fiber& fiber = m_fibers[i]; - if (isRope(fiber)) { - RopeImpl* nextRope = static_cast<RopeImpl*>(fiber); - if (nextRope->hasOneRef()) - workQueue.append(nextRope); - else - nextRope->deref(); - } else - static_cast<StringImpl*>(fiber)->deref(); - } -} - -void RopeImpl::destructNonRecursive() -{ - Vector<RopeImpl*, 32> workQueue; - - derefFibersNonRecursive(workQueue); - delete this; - - while (!workQueue.isEmpty()) { - RopeImpl* rope = workQueue.last(); - workQueue.removeLast(); - rope->derefFibersNonRecursive(workQueue); - delete rope; - } -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/RopeImpl.h b/JavaScriptCore/runtime/RopeImpl.h deleted file mode 100644 index dfacbf5..0000000 --- a/JavaScriptCore/runtime/RopeImpl.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2009, 2010 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 RopeImpl_h -#define RopeImpl_h - -#include <wtf/text/StringImpl.h> - -namespace JSC { - -class RopeImpl : public StringImplBase { -public: - // A RopeImpl is composed from a set of smaller strings called Fibers. - // Each Fiber in a rope is either StringImpl or another RopeImpl. - typedef StringImplBase* Fiber; - - // Creates a RopeImpl comprising of 'fiberCount' Fibers. - // The RopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the RopeImpl. - static PassRefPtr<RopeImpl> tryCreateUninitialized(unsigned fiberCount) - { - void* allocation; - if (tryFastMalloc(sizeof(RopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation)) - return adoptRef(new (allocation) RopeImpl(fiberCount)); - return 0; - } - - static bool isRope(Fiber fiber) - { - return !fiber->isStringImpl(); - } - - static void deref(Fiber fiber) - { - if (isRope(fiber)) - static_cast<RopeImpl*>(fiber)->deref(); - else - static_cast<StringImpl*>(fiber)->deref(); - } - - void initializeFiber(unsigned &index, Fiber fiber) - { - m_fibers[index++] = fiber; - fiber->ref(); - m_length += fiber->length(); - } - - unsigned fiberCount() { return m_size; } - Fiber* fibers() { return m_fibers; } - - ALWAYS_INLINE void deref() - { - m_refCountAndFlags -= s_refCountIncrement; - if (!(m_refCountAndFlags & s_refCountMask)) - destructNonRecursive(); - } - -private: - RopeImpl(unsigned fiberCount) - : StringImplBase(ConstructNonStringImpl) - , m_size(fiberCount) - { - } - - void destructNonRecursive(); - void derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue); - - bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; } - - unsigned m_size; - Fiber m_fibers[1]; -}; - -} - -#endif diff --git a/JavaScriptCore/runtime/ScopeChain.cpp b/JavaScriptCore/runtime/ScopeChain.cpp deleted file mode 100644 index 54c5082..0000000 --- a/JavaScriptCore/runtime/ScopeChain.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2008 Apple Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "ScopeChain.h" - -#include "JSActivation.h" -#include "JSGlobalObject.h" -#include "JSObject.h" -#include "PropertyNameArray.h" -#include <stdio.h> - -namespace JSC { - -#ifndef NDEBUG - -void ScopeChainNode::print() const -{ - ScopeChainIterator scopeEnd = end(); - for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) { - JSObject* o = *scopeIter; - PropertyNameArray propertyNames(globalObject->globalExec()); - o->getPropertyNames(globalObject->globalExec(), propertyNames); - PropertyNameArray::const_iterator propEnd = propertyNames.end(); - - fprintf(stderr, "----- [scope %p] -----\n", o); - for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) { - Identifier name = *propIter; - fprintf(stderr, "%s, ", name.ustring().utf8().data()); - } - fprintf(stderr, "\n"); - } -} - -#endif - -int ScopeChain::localDepth() const -{ - int scopeDepth = 0; - ScopeChainIterator iter = this->begin(); - ScopeChainIterator end = this->end(); - while (!(*iter)->inherits(&JSActivation::info)) { - ++iter; - if (iter == end) - break; - ++scopeDepth; - } - return scopeDepth; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/ScopeChain.h b/JavaScriptCore/runtime/ScopeChain.h deleted file mode 100644 index 0b15b67..0000000 --- a/JavaScriptCore/runtime/ScopeChain.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ScopeChain_h -#define ScopeChain_h - -#include "FastAllocBase.h" - -namespace JSC { - - class JSGlobalData; - class JSGlobalObject; - class JSObject; - class MarkStack; - class ScopeChainIterator; - - class ScopeChainNode : public FastAllocBase { - public: - ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis) - : next(next) - , object(object) - , globalData(globalData) - , globalObject(globalObject) - , globalThis(globalThis) - , refCount(1) - { - ASSERT(globalData); - ASSERT(globalObject); - } -#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; - globalObject = 0; - globalThis = 0; - } -#endif - - ScopeChainNode* next; - JSObject* object; - JSGlobalData* globalData; - JSGlobalObject* globalObject; - JSObject* globalThis; - int refCount; - - void deref() { ASSERT(refCount); if (--refCount == 0) { release();} } - void ref() { ASSERT(refCount); ++refCount; } - void release(); - - // Before calling "push" on a bare ScopeChainNode, a client should - // logically "copy" the node. Later, the client can "deref" the head - // of its chain of ScopeChainNodes to reclaim all the nodes it added - // after the logical copy, leaving nodes added before the logical copy - // (nodes shared with other clients) untouched. - ScopeChainNode* copy() - { - ref(); - return this; - } - - ScopeChainNode* push(JSObject*); - ScopeChainNode* pop(); - - ScopeChainIterator begin() const; - ScopeChainIterator end() const; - -#ifndef NDEBUG - void print() const; -#endif - }; - - inline ScopeChainNode* ScopeChainNode::push(JSObject* o) - { - ASSERT(o); - return new ScopeChainNode(this, o, globalData, globalObject, globalThis); - } - - inline ScopeChainNode* ScopeChainNode::pop() - { - ASSERT(next); - ScopeChainNode* result = next; - - if (--refCount != 0) - ++result->refCount; - else - delete this; - - return result; - } - - inline void ScopeChainNode::release() - { - // This function is only called by deref(), - // Deref ensures these conditions are true. - ASSERT(refCount == 0); - ScopeChainNode* n = this; - do { - ScopeChainNode* next = n->next; - delete n; - n = next; - } while (n && --n->refCount == 0); - } - - class ScopeChainIterator { - public: - ScopeChainIterator(const ScopeChainNode* node) - : m_node(node) - { - } - - JSObject* const & operator*() const { return m_node->object; } - JSObject* const * operator->() const { return &(operator*()); } - - ScopeChainIterator& operator++() { m_node = m_node->next; return *this; } - - // postfix ++ intentionally omitted - - bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; } - bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; } - - private: - const ScopeChainNode* m_node; - }; - - inline ScopeChainIterator ScopeChainNode::begin() const - { - return ScopeChainIterator(this); - } - - inline ScopeChainIterator ScopeChainNode::end() const - { - return ScopeChainIterator(0); - } - - class NoScopeChain {}; - - class ScopeChain { - friend class JIT; - public: - ScopeChain(NoScopeChain) - : m_node(0) - { - } - - ScopeChain(JSObject* o, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis) - : m_node(new ScopeChainNode(0, o, globalData, globalObject, globalThis)) - { - } - - ScopeChain(const ScopeChain& c) - : m_node(c.m_node->copy()) - { - } - - ScopeChain& operator=(const ScopeChain& c); - - explicit ScopeChain(ScopeChainNode* node) - : m_node(node->copy()) - { - } - - ~ScopeChain() - { - if (m_node) - m_node->deref(); -#ifndef NDEBUG - m_node = 0; -#endif - } - - void swap(ScopeChain&); - - ScopeChainNode* node() const { return m_node; } - - JSObject* top() const { return m_node->object; } - - ScopeChainIterator begin() const { return m_node->begin(); } - ScopeChainIterator end() const { return m_node->end(); } - - void push(JSObject* o) { m_node = m_node->push(o); } - - void pop() { m_node = m_node->pop(); } - void clear() { m_node->deref(); m_node = 0; } - - JSGlobalObject* globalObject() const { return m_node->globalObject; } - - void markAggregate(MarkStack&) const; - - // Caution: this should only be used if the codeblock this is being used - // with needs a full scope chain, otherwise this returns the depth of - // the preceeding call frame - // - // Returns the depth of the current call frame's scope chain - int localDepth() const; - -#ifndef NDEBUG - void print() const { m_node->print(); } -#endif - - private: - ScopeChainNode* m_node; - }; - - inline void ScopeChain::swap(ScopeChain& o) - { - ScopeChainNode* tmp = m_node; - m_node = o.m_node; - o.m_node = tmp; - } - - inline ScopeChain& ScopeChain::operator=(const ScopeChain& c) - { - ScopeChain tmp(c); - swap(tmp); - return *this; - } - -} // namespace JSC - -#endif // ScopeChain_h diff --git a/JavaScriptCore/runtime/ScopeChainMark.h b/JavaScriptCore/runtime/ScopeChainMark.h deleted file mode 100644 index 984d101..0000000 --- a/JavaScriptCore/runtime/ScopeChainMark.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ScopeChainMark_h -#define ScopeChainMark_h - -#include "ScopeChain.h" - -namespace JSC { - - inline void ScopeChain::markAggregate(MarkStack& markStack) const - { - for (ScopeChainNode* n = m_node; n; n = n->next) - markStack.append(n->object); - } - -} // namespace JSC - -#endif // ScopeChainMark_h diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp deleted file mode 100644 index f358727..0000000 --- a/JavaScriptCore/runtime/SmallStrings.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "SmallStrings.h" - -#include "JSGlobalObject.h" -#include "JSString.h" -#include <wtf/Noncopyable.h> -#include <wtf/PassOwnPtr.h> - -namespace JSC { - -static const unsigned numCharactersToStore = 0x100; - -static inline bool isMarked(JSString* string) -{ - return string && Heap::isCellMarked(string); -} - -class SmallStringsStorage : public Noncopyable { -public: - SmallStringsStorage(); - - StringImpl* rep(unsigned char character) { return m_reps[character].get(); } - -private: - RefPtr<StringImpl> m_reps[numCharactersToStore]; -}; - -SmallStringsStorage::SmallStringsStorage() -{ - UChar* characterBuffer = 0; - RefPtr<StringImpl> baseString = StringImpl::createUninitialized(numCharactersToStore, characterBuffer); - for (unsigned i = 0; i < numCharactersToStore; ++i) { - characterBuffer[i] = i; - m_reps[i] = StringImpl::create(baseString, i, 1); - } -} - -SmallStrings::SmallStrings() -{ - COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage); - clear(); -} - -SmallStrings::~SmallStrings() -{ -} - -void SmallStrings::markChildren(MarkStack& markStack) -{ - /* - Our hypothesis is that small strings are very common. So, we cache them - to avoid GC churn. However, in cases where this hypothesis turns out to - be false -- including the degenerate case where all JavaScript execution - has terminated -- we don't want to waste memory. - - To test our hypothesis, we check if any small string has been marked. If - so, it's probably reasonable to mark the rest. If not, we clear the cache. - */ - - bool isAnyStringMarked = isMarked(m_emptyString); - for (unsigned i = 0; i < numCharactersToStore && !isAnyStringMarked; ++i) - isAnyStringMarked = isMarked(m_singleCharacterStrings[i]); - - if (!isAnyStringMarked) { - clear(); - return; - } - - if (m_emptyString) - markStack.append(m_emptyString); - for (unsigned i = 0; i < numCharactersToStore; ++i) { - if (m_singleCharacterStrings[i]) - markStack.append(m_singleCharacterStrings[i]); - } -} - -void SmallStrings::clear() -{ - m_emptyString = 0; - for (unsigned i = 0; i < numCharactersToStore; ++i) - m_singleCharacterStrings[i] = 0; -} - -unsigned SmallStrings::count() const -{ - unsigned count = 0; - if (m_emptyString) - ++count; - for (unsigned i = 0; i < numCharactersToStore; ++i) { - if (m_singleCharacterStrings[i]) - ++count; - } - return count; -} - -void SmallStrings::createEmptyString(JSGlobalData* globalData) -{ - ASSERT(!m_emptyString); - m_emptyString = new (globalData) JSString(globalData, "", JSString::HasOtherOwner); -} - -void SmallStrings::createSingleCharacterString(JSGlobalData* globalData, unsigned char character) -{ - if (!m_storage) - m_storage = adoptPtr(new SmallStringsStorage); - ASSERT(!m_singleCharacterStrings[character]); - m_singleCharacterStrings[character] = new (globalData) JSString(globalData, PassRefPtr<StringImpl>(m_storage->rep(character)), JSString::HasOtherOwner); -} - -StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character) -{ - if (!m_storage) - m_storage = adoptPtr(new SmallStringsStorage); - return m_storage->rep(character); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h deleted file mode 100644 index d1ebfb1..0000000 --- a/JavaScriptCore/runtime/SmallStrings.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SmallStrings_h -#define SmallStrings_h - -#include "UString.h" -#include <wtf/FixedArray.h> -#include <wtf/OwnPtr.h> - -namespace JSC { - - class JSGlobalData; - class JSString; - class MarkStack; - class SmallStringsStorage; - - class SmallStrings : public Noncopyable { - public: - SmallStrings(); - ~SmallStrings(); - - JSString* emptyString(JSGlobalData* globalData) - { - if (!m_emptyString) - createEmptyString(globalData); - return m_emptyString; - } - JSString* singleCharacterString(JSGlobalData* globalData, unsigned char character) - { - if (!m_singleCharacterStrings[character]) - createSingleCharacterString(globalData, character); - return m_singleCharacterStrings[character]; - } - - StringImpl* singleCharacterStringRep(unsigned char character); - - void markChildren(MarkStack&); - void clear(); - - unsigned count() const; -#if ENABLE(JIT) - JSString** singleCharacterStrings() { return m_singleCharacterStrings.data(); } -#endif - private: - void createEmptyString(JSGlobalData*); - void createSingleCharacterString(JSGlobalData*, unsigned char); - - JSString* m_emptyString; - FixedArray<JSString*, 0x100> m_singleCharacterStrings; - OwnPtr<SmallStringsStorage> m_storage; - }; - -} // namespace JSC - -#endif // SmallStrings_h diff --git a/JavaScriptCore/runtime/StrictEvalActivation.cpp b/JavaScriptCore/runtime/StrictEvalActivation.cpp deleted file mode 100644 index 5bb013b..0000000 --- a/JavaScriptCore/runtime/StrictEvalActivation.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 "StrictEvalActivation.h" - -namespace JSC { - -StrictEvalActivation::StrictEvalActivation(ExecState* exec) - : JSObject(exec->globalData().strictEvalActivationStructure) -{ -} - -bool StrictEvalActivation::deleteProperty(ExecState*, const Identifier&) -{ - return false; -} - -JSObject* StrictEvalActivation::toThisObject(ExecState* exec) const -{ - return exec->globalThisValue(); -} - -JSValue StrictEvalActivation::toStrictThisObject(ExecState*) const -{ - return jsNull(); -} - -} diff --git a/JavaScriptCore/runtime/StrictEvalActivation.h b/JavaScriptCore/runtime/StrictEvalActivation.h deleted file mode 100644 index 1385eec..0000000 --- a/JavaScriptCore/runtime/StrictEvalActivation.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010 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. 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 INC. 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 StrictEvalActivation_h -#define StrictEvalActivation_h - -#include "JSObject.h" - -namespace JSC { - -class StrictEvalActivation : public JSObject { -public: - StrictEvalActivation(ExecState*); - virtual bool deleteProperty(ExecState*, const Identifier&); - virtual JSObject* toThisObject(ExecState*) const; - virtual JSValue toStrictThisObject(ExecState*) const; -}; - -} // namespace JSC - -#endif // StrictEvalActivation_h diff --git a/JavaScriptCore/runtime/StringConstructor.cpp b/JavaScriptCore/runtime/StringConstructor.cpp deleted file mode 100644 index 101650c..0000000 --- a/JavaScriptCore/runtime/StringConstructor.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "StringConstructor.h" - -#include "Executable.h" -#include "JITCode.h" -#include "JSFunction.h" -#include "JSGlobalObject.h" -#include "PrototypeFunction.h" -#include "StringPrototype.h" - -namespace JSC { - -static NEVER_INLINE JSValue stringFromCharCodeSlowCase(ExecState* exec) -{ - unsigned length = exec->argumentCount(); - UChar* buf; - PassRefPtr<StringImpl> impl = StringImpl::createUninitialized(length, buf); - for (unsigned i = 0; i < length; ++i) - buf[i] = static_cast<UChar>(exec->argument(i).toUInt32(exec)); - return jsString(exec, impl); -} - -static EncodedJSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec) -{ - if (LIKELY(exec->argumentCount() == 1)) - return JSValue::encode(jsSingleCharacterString(exec, exec->argument(0).toUInt32(exec))); - return JSValue::encode(stringFromCharCodeSlowCase(exec)); -} - -ASSERT_CLASS_FITS_IN_CELL(StringConstructor); - -StringConstructor::StringConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, StringPrototype* stringPrototype) - : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, stringPrototype->classInfo()->className)) -{ - // ECMA 15.5.3.1 String.prototype - putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete); - - // ECMA 15.5.3.2 fromCharCode() -#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL) - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, exec->globalData().getHostFunction(stringFromCharCode, fromCharCodeThunkGenerator)), DontEnum); -#else - putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, globalObject, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum); -#endif - // no. of arguments for constructor - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(1), ReadOnly | DontEnum | DontDelete); -} - -// ECMA 15.5.2 -static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec) -{ - if (!exec->argumentCount()) - return JSValue::encode(new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure())); - return JSValue::encode(new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), exec->argument(0).toString(exec))); -} - -ConstructType StringConstructor::getConstructData(ConstructData& constructData) -{ - constructData.native.function = constructWithStringConstructor; - return ConstructTypeHost; -} - -// ECMA 15.5.1 -static EncodedJSValue JSC_HOST_CALL callStringConstructor(ExecState* exec) -{ - if (!exec->argumentCount()) - return JSValue::encode(jsEmptyString(exec)); - return JSValue::encode(jsString(exec, exec->argument(0).toString(exec))); -} - -CallType StringConstructor::getCallData(CallData& callData) -{ - callData.native.function = callStringConstructor; - return CallTypeHost; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/StringConstructor.h b/JavaScriptCore/runtime/StringConstructor.h deleted file mode 100644 index 20f3a52..0000000 --- a/JavaScriptCore/runtime/StringConstructor.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef StringConstructor_h -#define StringConstructor_h - -#include "InternalFunction.h" - -namespace JSC { - - class StringPrototype; - - class StringConstructor : public InternalFunction { - public: - StringConstructor(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure, StringPrototype*); - - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); - }; - -} // namespace JSC - -#endif // StringConstructor_h diff --git a/JavaScriptCore/runtime/StringObject.cpp b/JavaScriptCore/runtime/StringObject.cpp deleted file mode 100644 index dc27618..0000000 --- a/JavaScriptCore/runtime/StringObject.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "StringObject.h" - -#include "PropertyNameArray.h" - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(StringObject); - -const ClassInfo StringObject::info = { "String", 0, 0, 0 }; - -StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure) - : JSWrapperObject(structure) -{ - setInternalValue(jsEmptyString(exec)); -} - -StringObject::StringObject(NonNullPassRefPtr<Structure> structure, JSString* string) - : JSWrapperObject(structure) -{ - setInternalValue(string); -} - -StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string) - : JSWrapperObject(structure) -{ - setInternalValue(jsString(exec, string)); -} - -bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (internalValue()->getStringPropertySlot(exec, propertyName, slot)) - return true; - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) -{ - if (internalValue()->getStringPropertySlot(exec, propertyName, slot)) - return true; - return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot); -} - -bool StringObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor)) - return true; - return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - -void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) -{ - if (propertyName == exec->propertyNames().length) - return; - JSObject::put(exec, propertyName, value, slot); -} - -bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - if (propertyName == exec->propertyNames().length) - return false; - bool isStrictUInt32; - unsigned i = propertyName.toUInt32(isStrictUInt32); - if (isStrictUInt32 && internalValue()->canGetIndex(i)) - return false; - return JSObject::deleteProperty(exec, propertyName); -} - -void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) -{ - int size = internalValue()->length(); - for (int i = 0; i < size; ++i) - propertyNames.add(Identifier(exec, UString::number(i))); - if (mode == IncludeDontEnumProperties) - propertyNames.add(exec->propertyNames().length); - return JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/StringObject.h b/JavaScriptCore/runtime/StringObject.h deleted file mode 100644 index e3add77..0000000 --- a/JavaScriptCore/runtime/StringObject.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef StringObject_h -#define StringObject_h - -#include "JSWrapperObject.h" -#include "JSString.h" - -namespace JSC { - - class StringObject : public JSWrapperObject { - public: - StringObject(ExecState*, NonNullPassRefPtr<Structure>); - StringObject(ExecState*, NonNullPassRefPtr<Structure>, const UString&); - - static StringObject* create(ExecState*, JSString*); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&); - virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); - - virtual const ClassInfo* classInfo() const { return &info; } - static const JS_EXPORTDATA ClassInfo info; - - JSString* internalValue() const { return asString(JSWrapperObject::internalValue());} - - static PassRefPtr<Structure> createStructure(JSValue prototype) - { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags; - StringObject(NonNullPassRefPtr<Structure>, JSString*); - }; - - StringObject* asStringObject(JSValue); - - inline StringObject* asStringObject(JSValue value) - { - ASSERT(asObject(value)->inherits(&StringObject::info)); - return static_cast<StringObject*>(asObject(value)); - } - -} // namespace JSC - -#endif // StringObject_h diff --git a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h deleted file mode 100644 index 43c3e38..0000000 --- a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef StringObjectThatMasqueradesAsUndefined_h -#define StringObjectThatMasqueradesAsUndefined_h - -#include "JSGlobalObject.h" -#include "StringObject.h" -#include "UString.h" - -namespace JSC { - - // WebCore uses this to make style.filter undetectable - class StringObjectThatMasqueradesAsUndefined : public StringObject { - public: - static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string) - { - return new (exec) StringObjectThatMasqueradesAsUndefined(exec, - createStructure(exec->lexicalGlobalObject()->stringPrototype()), string); - } - - private: - StringObjectThatMasqueradesAsUndefined(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string) - : StringObject(exec, structure, string) - { - } - - static PassRefPtr<Structure> createStructure(JSValue proto) - { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); - } - - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags; - - virtual bool toBoolean(ExecState*) const { return false; } - }; - -} // namespace JSC - -#endif // StringObjectThatMasqueradesAsUndefined_h diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp deleted file mode 100644 index 8b3d056..0000000 --- a/JavaScriptCore/runtime/StringPrototype.cpp +++ /dev/null @@ -1,1155 +0,0 @@ -/* - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "StringPrototype.h" - -#include "CachedCall.h" -#include "Error.h" -#include "Executable.h" -#include "JSGlobalObjectFunctions.h" -#include "JSArray.h" -#include "JSFunction.h" -#include "JSStringBuilder.h" -#include "Lookup.h" -#include "ObjectPrototype.h" -#include "Operations.h" -#include "PropertyNameArray.h" -#include "RegExpCache.h" -#include "RegExpConstructor.h" -#include "RegExpObject.h" -#include <wtf/ASCIICType.h> -#include <wtf/MathExtras.h> -#include <wtf/unicode/Collator.h> - -using namespace WTF; - -namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(StringPrototype); - -static EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncBold(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSub(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncSup(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*); -static EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*); - -} - -#include "StringPrototype.lut.h" - -namespace JSC { - -const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, ExecState::stringTable }; - -/* Source for StringPrototype.lut.h -@begin stringTable 26 - toString stringProtoFuncToString DontEnum|Function 0 - valueOf stringProtoFuncToString DontEnum|Function 0 - charAt stringProtoFuncCharAt DontEnum|Function 1 - charCodeAt stringProtoFuncCharCodeAt DontEnum|Function 1 - concat stringProtoFuncConcat DontEnum|Function 1 - indexOf stringProtoFuncIndexOf DontEnum|Function 1 - lastIndexOf stringProtoFuncLastIndexOf DontEnum|Function 1 - match stringProtoFuncMatch DontEnum|Function 1 - replace stringProtoFuncReplace DontEnum|Function 2 - search stringProtoFuncSearch DontEnum|Function 1 - slice stringProtoFuncSlice DontEnum|Function 2 - split stringProtoFuncSplit DontEnum|Function 2 - substr stringProtoFuncSubstr DontEnum|Function 2 - substring stringProtoFuncSubstring DontEnum|Function 2 - toLowerCase stringProtoFuncToLowerCase DontEnum|Function 0 - toUpperCase stringProtoFuncToUpperCase DontEnum|Function 0 - localeCompare stringProtoFuncLocaleCompare DontEnum|Function 1 - - # toLocaleLowerCase and toLocaleUpperCase are currently identical to toLowerCase and toUpperCase - toLocaleLowerCase stringProtoFuncToLowerCase DontEnum|Function 0 - toLocaleUpperCase stringProtoFuncToUpperCase DontEnum|Function 0 - - big stringProtoFuncBig DontEnum|Function 0 - small stringProtoFuncSmall DontEnum|Function 0 - blink stringProtoFuncBlink DontEnum|Function 0 - bold stringProtoFuncBold DontEnum|Function 0 - fixed stringProtoFuncFixed DontEnum|Function 0 - italics stringProtoFuncItalics DontEnum|Function 0 - strike stringProtoFuncStrike DontEnum|Function 0 - sub stringProtoFuncSub DontEnum|Function 0 - sup stringProtoFuncSup DontEnum|Function 0 - fontcolor stringProtoFuncFontcolor DontEnum|Function 1 - fontsize stringProtoFuncFontsize DontEnum|Function 1 - anchor stringProtoFuncAnchor DontEnum|Function 1 - link stringProtoFuncLink DontEnum|Function 1 - trim stringProtoFuncTrim DontEnum|Function 0 - trimLeft stringProtoFuncTrimLeft DontEnum|Function 0 - trimRight stringProtoFuncTrimRight DontEnum|Function 0 -@end -*/ - -// ECMA 15.5.4 -StringPrototype::StringPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure) - : StringObject(exec, structure) -{ - putAnonymousValue(0, globalObject); - // The constructor will be added later, after StringConstructor has been built - putDirectWithoutTransition(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); -} - -bool StringPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot) -{ - return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, slot); -} - -bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - return getStaticFunctionDescriptor<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, descriptor); -} - -// ------------------------------ Functions -------------------------- - -static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, size_t i) -{ - Vector<UChar> substitutedReplacement; - int offset = 0; - do { - if (i + 1 == replacement.length()) - break; - - UChar ref = replacement[i + 1]; - if (ref == '$') { - // "$$" -> "$" - ++i; - substitutedReplacement.append(replacement.characters() + offset, i - offset); - offset = i + 1; - continue; - } - - int backrefStart; - int backrefLength; - int advance = 0; - if (ref == '&') { - backrefStart = ovector[0]; - backrefLength = ovector[1] - backrefStart; - } else if (ref == '`') { - backrefStart = 0; - backrefLength = ovector[0]; - } else if (ref == '\'') { - backrefStart = ovector[1]; - backrefLength = source.length() - backrefStart; - } else if (reg && ref >= '0' && ref <= '9') { - // 1- and 2-digit back references are allowed - unsigned backrefIndex = ref - '0'; - if (backrefIndex > reg->numSubpatterns()) - continue; - if (replacement.length() > i + 2) { - ref = replacement[i + 2]; - if (ref >= '0' && ref <= '9') { - backrefIndex = 10 * backrefIndex + ref - '0'; - if (backrefIndex > reg->numSubpatterns()) - backrefIndex = backrefIndex / 10; // Fall back to the 1-digit reference - else - advance = 1; - } - } - if (!backrefIndex) - continue; - backrefStart = ovector[2 * backrefIndex]; - backrefLength = ovector[2 * backrefIndex + 1] - backrefStart; - } else - continue; - - if (i - offset) - substitutedReplacement.append(replacement.characters() + offset, i - offset); - i += 1 + advance; - offset = i + 1; - if (backrefStart >= 0) - substitutedReplacement.append(source.characters() + backrefStart, backrefLength); - } while ((i = replacement.find('$', i + 1)) != notFound); - - if (replacement.length() - offset) - substitutedReplacement.append(replacement.characters() + offset, replacement.length() - offset); - - substitutedReplacement.shrinkToFit(); - return UString::adopt(substitutedReplacement); -} - -static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg) -{ - size_t i = replacement.find('$', 0); - if (UNLIKELY(i != notFound)) - return substituteBackreferencesSlow(replacement, source, ovector, reg, i); - return replacement; -} - -static inline int localeCompare(const UString& a, const UString& b) -{ - return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.characters()), a.length(), reinterpret_cast<const ::UChar*>(b.characters()), b.length()); -} - -struct StringRange { -public: - StringRange(int pos, int len) - : position(pos) - , length(len) - { - } - - StringRange() - { - } - - int position; - int length; -}; - -static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount) -{ - if (rangeCount == 1 && separatorCount == 0) { - int sourceSize = source.length(); - int position = substringRanges[0].position; - int length = substringRanges[0].length; - if (position <= 0 && length >= sourceSize) - return sourceVal; - // We could call UString::substr, but this would result in redundant checks - return jsString(exec, StringImpl::create(source.impl(), max(0, position), min(sourceSize, length))); - } - - int totalLength = 0; - for (int i = 0; i < rangeCount; i++) - totalLength += substringRanges[i].length; - for (int i = 0; i < separatorCount; i++) - totalLength += separators[i].length(); - - if (totalLength == 0) - return jsString(exec, ""); - - UChar* buffer; - PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer); - if (!impl) - return throwOutOfMemoryError(exec); - - int maxCount = max(rangeCount, separatorCount); - int bufferPos = 0; - for (int i = 0; i < maxCount; i++) { - if (i < rangeCount) { - if (int srcLen = substringRanges[i].length) { - StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, srcLen); - bufferPos += srcLen; - } - } - if (i < separatorCount) { - if (int sepLen = separators[i].length()) { - StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), sepLen); - bufferPos += sepLen; - } - } - } - - return jsString(exec, impl); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - JSString* sourceVal = thisValue.toThisJSString(exec); - JSValue pattern = exec->argument(0); - JSValue replacement = exec->argument(1); - - UString replacementString; - CallData callData; - CallType callType = getCallData(replacement, callData); - if (callType == CallTypeNone) - replacementString = replacement.toString(exec); - - if (pattern.inherits(&RegExpObject::info)) { - const UString& source = sourceVal->value(exec); - unsigned sourceLen = source.length(); - if (exec->hadException()) - return JSValue::encode(JSValue()); - RegExp* reg = asRegExpObject(pattern)->regExp(); - bool global = reg->global(); - - RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); - - int lastIndex = 0; - unsigned startPosition = 0; - - Vector<StringRange, 16> sourceRanges; - Vector<UString, 16> replacements; - - // This is either a loop (if global is set) or a one-way (if not). - if (global && callType == CallTypeJS) { - // reg->numSubpatterns() + 1 for pattern args, + 2 for match start and sourceValue - int argCount = reg->numSubpatterns() + 1 + 2; - JSFunction* func = asFunction(replacement); - CachedCall cachedCall(exec, func, argCount); - if (exec->hadException()) - return JSValue::encode(jsNull()); - while (true) { - int matchIndex; - int matchLen = 0; - int* ovector; - regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); - if (matchIndex < 0) - break; - - sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex)); - - int completeMatchStart = ovector[0]; - unsigned i = 0; - for (; i < reg->numSubpatterns() + 1; ++i) { - int matchStart = ovector[i * 2]; - int matchLen = ovector[i * 2 + 1] - matchStart; - - if (matchStart < 0) - cachedCall.setArgument(i, jsUndefined()); - else - cachedCall.setArgument(i, jsSubstring(exec, source, matchStart, matchLen)); - } - - cachedCall.setArgument(i++, jsNumber(completeMatchStart)); - cachedCall.setArgument(i++, sourceVal); - - cachedCall.setThis(exec->globalThisValue()); - JSValue result = cachedCall.call(); - if (LIKELY(result.isString())) - replacements.append(asString(result)->value(exec)); - else - replacements.append(result.toString(cachedCall.newCallFrame(exec))); - if (exec->hadException()) - break; - - lastIndex = matchIndex + matchLen; - startPosition = lastIndex; - - // special case of empty match - if (matchLen == 0) { - startPosition++; - if (startPosition > sourceLen) - break; - } - } - } else { - do { - int matchIndex; - int matchLen = 0; - int* ovector; - regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector); - if (matchIndex < 0) - break; - - if (callType != CallTypeNone) { - sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex)); - - int completeMatchStart = ovector[0]; - MarkedArgumentBuffer args; - - for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) { - int matchStart = ovector[i * 2]; - int matchLen = ovector[i * 2 + 1] - matchStart; - - if (matchStart < 0) - args.append(jsUndefined()); - else - args.append(jsSubstring(exec, source, matchStart, matchLen)); - } - - args.append(jsNumber(completeMatchStart)); - args.append(sourceVal); - - replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec)); - if (exec->hadException()) - break; - } else { - int replLen = replacementString.length(); - if (lastIndex < matchIndex || replLen) { - sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex)); - - if (replLen) - replacements.append(substituteBackreferences(replacementString, source, ovector, reg)); - else - replacements.append(UString()); - } - } - - lastIndex = matchIndex + matchLen; - startPosition = lastIndex; - - // special case of empty match - if (matchLen == 0) { - startPosition++; - if (startPosition > sourceLen) - break; - } - } while (global); - } - - if (!lastIndex && replacements.isEmpty()) - return JSValue::encode(sourceVal); - - if (static_cast<unsigned>(lastIndex) < sourceLen) - sourceRanges.append(StringRange(lastIndex, sourceLen - lastIndex)); - - return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size())); - } - - // Not a regular expression, so treat the pattern as a string. - - UString patternString = pattern.toString(exec); - // Special case for single character patterns without back reference replacement - if (patternString.length() == 1 && callType == CallTypeNone && replacementString.find('$', 0) == notFound) - return JSValue::encode(sourceVal->replaceCharacter(exec, patternString[0], replacementString)); - - const UString& source = sourceVal->value(exec); - size_t matchPos = source.find(patternString); - - if (matchPos == notFound) - return JSValue::encode(sourceVal); - - int matchLen = patternString.length(); - if (callType != CallTypeNone) { - MarkedArgumentBuffer args; - args.append(jsSubstring(exec, source, matchPos, matchLen)); - args.append(jsNumber(matchPos)); - args.append(sourceVal); - - replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec); - } - - size_t matchEnd = matchPos + matchLen; - int ovector[2] = { matchPos, matchEnd }; - return JSValue::encode(jsString(exec, source.substringSharingImpl(0, matchPos), substituteBackreferences(replacementString, source, ovector, 0), source.substringSharingImpl(matchEnd))); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - // Also used for valueOf. - - if (thisValue.isString()) - return JSValue::encode(thisValue); - - if (thisValue.inherits(&StringObject::info)) - return JSValue::encode(asStringObject(thisValue)->internalValue()); - - return throwVMTypeError(exec); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - unsigned len = s.length(); - JSValue a0 = exec->argument(0); - if (a0.isUInt32()) { - uint32_t i = a0.asUInt32(); - if (i < len) - return JSValue::encode(jsSingleCharacterSubstring(exec, s, i)); - return JSValue::encode(jsEmptyString(exec)); - } - double dpos = a0.toInteger(exec); - if (dpos >= 0 && dpos < len) - return JSValue::encode(jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos))); - return JSValue::encode(jsEmptyString(exec)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - unsigned len = s.length(); - JSValue a0 = exec->argument(0); - if (a0.isUInt32()) { - uint32_t i = a0.asUInt32(); - if (i < len) - return JSValue::encode(jsNumber(s.characters()[i])); - return JSValue::encode(jsNaN()); - } - double dpos = a0.toInteger(exec); - if (dpos >= 0 && dpos < len) - return JSValue::encode(jsNumber(s[static_cast<int>(dpos)])); - return JSValue::encode(jsNaN()); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isString() && (exec->argumentCount() == 1)) { - JSValue v = exec->argument(0); - return JSValue::encode(v.isString() - ? jsString(exec, asString(thisValue), asString(v)) - : jsString(exec, asString(thisValue), v.toString(exec))); - } - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - return JSValue::encode(jsString(exec, thisValue)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - int len = s.length(); - - JSValue a0 = exec->argument(0); - JSValue a1 = exec->argument(1); - UString u2 = a0.toString(exec); - int pos; - if (a1.isUndefined()) - pos = 0; - else if (a1.isUInt32()) - pos = min<uint32_t>(a1.asUInt32(), len); - else { - double dpos = a1.toInteger(exec); - if (dpos < 0) - dpos = 0; - else if (dpos > len) - dpos = len; - pos = static_cast<int>(dpos); - } - - size_t result = s.find(u2, pos); - if (result == notFound) - return JSValue::encode(jsNumber(-1)); - return JSValue::encode(jsNumber(result)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - int len = s.length(); - - JSValue a0 = exec->argument(0); - JSValue a1 = exec->argument(1); - - UString u2 = a0.toString(exec); - double dpos = a1.toIntegerPreserveNaN(exec); - if (dpos < 0) - dpos = 0; - else if (!(dpos <= len)) // true for NaN - dpos = len; -#if OS(SYMBIAN) - // Work around for broken NaN compare operator - else if (isnan(dpos)) - dpos = len; -#endif - - size_t result = s.reverseFind(u2, static_cast<unsigned>(dpos)); - if (result == notFound) - return JSValue::encode(jsNumber(-1)); - return JSValue::encode(jsNumber(result)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - - JSValue a0 = exec->argument(0); - - UString u = s; - RefPtr<RegExp> reg; - RegExpObject* imp = 0; - if (a0.inherits(&RegExpObject::info)) - reg = asRegExpObject(a0)->regExp(); - else { - /* - * ECMA 15.5.4.12 String.prototype.search (regexp) - * If regexp is not an object whose [[Class]] property is "RegExp", it is - * replaced with the result of the expression new RegExp(regexp). - */ - reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString()); - } - RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); - int pos; - int matchLength = 0; - regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); - if (!(reg->global())) { - // case without 'g' flag is handled like RegExp.prototype.exec - if (pos < 0) - return JSValue::encode(jsNull()); - return JSValue::encode(regExpConstructor->arrayOfMatches(exec)); - } - - // return array of matches - MarkedArgumentBuffer list; - int lastIndex = 0; - while (pos >= 0) { - list.append(jsSubstring(exec, u, pos, matchLength)); - lastIndex = pos; - pos += matchLength == 0 ? 1 : matchLength; - regExpConstructor->performMatch(reg.get(), u, pos, pos, matchLength); - } - if (imp) - imp->setLastIndex(lastIndex); - if (list.isEmpty()) { - // if there are no matches at all, it's important to return - // Null instead of an empty array, because this matches - // other browsers and because Null is a false value. - return JSValue::encode(jsNull()); - } - - return JSValue::encode(constructArray(exec, list)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - - JSValue a0 = exec->argument(0); - - UString u = s; - RefPtr<RegExp> reg; - if (a0.inherits(&RegExpObject::info)) - reg = asRegExpObject(a0)->regExp(); - else { - /* - * ECMA 15.5.4.12 String.prototype.search (regexp) - * If regexp is not an object whose [[Class]] property is "RegExp", it is - * replaced with the result of the expression new RegExp(regexp). - */ - reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString()); - } - RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); - int pos; - int matchLength = 0; - regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); - return JSValue::encode(jsNumber(pos)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - int len = s.length(); - - JSValue a0 = exec->argument(0); - JSValue a1 = exec->argument(1); - - // The arg processing is very much like ArrayProtoFunc::Slice - double start = a0.toInteger(exec); - double end = a1.isUndefined() ? len : a1.toInteger(exec); - double from = start < 0 ? len + start : start; - double to = end < 0 ? len + end : end; - if (to > from && to > 0 && from < len) { - if (from < 0) - from = 0; - if (to > len) - to = len; - return JSValue::encode(jsSubstring(exec, s, static_cast<unsigned>(from), static_cast<unsigned>(to) - static_cast<unsigned>(from))); - } - - return JSValue::encode(jsEmptyString(exec)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - UString s = thisValue.toThisString(exec); - - JSValue a0 = exec->argument(0); - JSValue a1 = exec->argument(1); - - JSArray* result = constructEmptyArray(exec); - unsigned i = 0; - unsigned p0 = 0; - unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec); - if (a0.inherits(&RegExpObject::info)) { - RegExp* reg = asRegExpObject(a0)->regExp(); - if (s.isEmpty() && reg->match(s, 0) >= 0) { - // empty string matched by regexp -> empty array - return JSValue::encode(result); - } - unsigned pos = 0; - while (i != limit && pos < s.length()) { - Vector<int, 32> ovector; - int mpos = reg->match(s, pos, &ovector); - if (mpos < 0) - break; - int mlen = ovector[1] - ovector[0]; - pos = mpos + (mlen == 0 ? 1 : mlen); - if (static_cast<unsigned>(mpos) != p0 || mlen) { - result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0)); - p0 = mpos + mlen; - } - for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) { - int spos = ovector[si * 2]; - if (spos < 0) - result->put(exec, i++, jsUndefined()); - else - result->put(exec, i++, jsSubstring(exec, s, spos, ovector[si * 2 + 1] - spos)); - } - } - } else { - UString u2 = a0.toString(exec); - if (u2.isEmpty()) { - if (s.isEmpty()) { - // empty separator matches empty string -> empty array - return JSValue::encode(result); - } - while (i != limit && p0 < s.length() - 1) - result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++)); - } else { - size_t pos; - while (i != limit && (pos = s.find(u2, p0)) != notFound) { - result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0)); - p0 = pos + u2.length(); - } - } - } - - // add remaining string - if (i != limit) - result->put(exec, i++, jsSubstring(exec, s, p0, s.length() - p0)); - - return JSValue::encode(result); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - unsigned len; - JSString* jsString = 0; - UString uString; - if (thisValue.isString()) { - jsString = static_cast<JSString*>(thisValue.asCell()); - len = jsString->length(); - } else { - uString = thisValue.toThisObject(exec)->toString(exec); - len = uString.length(); - } - - JSValue a0 = exec->argument(0); - JSValue a1 = exec->argument(1); - - double start = a0.toInteger(exec); - double length = a1.isUndefined() ? len : a1.toInteger(exec); - if (start >= len || length <= 0) - return JSValue::encode(jsEmptyString(exec)); - if (start < 0) { - start += len; - if (start < 0) - start = 0; - } - if (start + length > len) - length = len - start; - unsigned substringStart = static_cast<unsigned>(start); - unsigned substringLength = static_cast<unsigned>(length); - if (jsString) - return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength)); - return JSValue::encode(jsSubstring(exec, uString, substringStart, substringLength)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - int len; - JSString* jsString = 0; - UString uString; - if (thisValue.isString()) { - jsString = static_cast<JSString*>(thisValue.asCell()); - len = jsString->length(); - } else { - uString = thisValue.toThisObject(exec)->toString(exec); - len = uString.length(); - } - - JSValue a0 = exec->argument(0); - JSValue a1 = exec->argument(1); - - double start = a0.toNumber(exec); - double end; - if (!(start >= 0)) // check for negative values or NaN - start = 0; - else if (start > len) - start = len; - if (a1.isUndefined()) - end = len; - else { - end = a1.toNumber(exec); - if (!(end >= 0)) // check for negative values or NaN - end = 0; - else if (end > len) - end = len; - } - if (start > end) { - double temp = end; - end = start; - start = temp; - } - unsigned substringStart = static_cast<unsigned>(start); - unsigned substringLength = static_cast<unsigned>(end) - substringStart; - if (jsString) - return JSValue::encode(jsSubstring(exec, jsString, substringStart, substringLength)); - return JSValue::encode(jsSubstring(exec, uString, substringStart, substringLength)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - JSString* sVal = thisValue.toThisJSString(exec); - const UString& s = sVal->value(exec); - - int sSize = s.length(); - if (!sSize) - return JSValue::encode(sVal); - - const UChar* sData = s.characters(); - Vector<UChar> buffer(sSize); - - UChar ored = 0; - for (int i = 0; i < sSize; i++) { - UChar c = sData[i]; - ored |= c; - buffer[i] = toASCIILower(c); - } - if (!(ored & ~0x7f)) - return JSValue::encode(jsString(exec, UString::adopt(buffer))); - - bool error; - int length = Unicode::toLower(buffer.data(), sSize, sData, sSize, &error); - if (error) { - buffer.resize(length); - length = Unicode::toLower(buffer.data(), length, sData, sSize, &error); - if (error) - return JSValue::encode(sVal); - } - if (length == sSize) { - if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0) - return JSValue::encode(sVal); - } else - buffer.resize(length); - return JSValue::encode(jsString(exec, UString::adopt(buffer))); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - JSString* sVal = thisValue.toThisJSString(exec); - const UString& s = sVal->value(exec); - - int sSize = s.length(); - if (!sSize) - return JSValue::encode(sVal); - - const UChar* sData = s.characters(); - Vector<UChar> buffer(sSize); - - UChar ored = 0; - for (int i = 0; i < sSize; i++) { - UChar c = sData[i]; - ored |= c; - buffer[i] = toASCIIUpper(c); - } - if (!(ored & ~0x7f)) - return JSValue::encode(jsString(exec, UString::adopt(buffer))); - - bool error; - int length = Unicode::toUpper(buffer.data(), sSize, sData, sSize, &error); - if (error) { - buffer.resize(length); - length = Unicode::toUpper(buffer.data(), length, sData, sSize, &error); - if (error) - return JSValue::encode(sVal); - } - if (length == sSize) { - if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0) - return JSValue::encode(sVal); - } else - buffer.resize(length); - return JSValue::encode(jsString(exec, UString::adopt(buffer))); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec) -{ - if (exec->argumentCount() < 1) - return JSValue::encode(jsNumber(0)); - - JSValue thisValue = exec->hostThisValue(); - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwVMTypeError(exec); - - UString s = thisValue.toThisString(exec); - JSValue a0 = exec->argument(0); - return JSValue::encode(jsNumber(localeCompare(s, a0.toString(exec)))); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<big>", s, "</big>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<small>", s, "</small>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<blink>", s, "</blink>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<b>", s, "</b>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<tt>", s, "</tt>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<i>", s, "</i>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<strike>", s, "</strike>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<sub>", s, "</sub>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - return JSValue::encode(jsMakeNontrivialString(exec, "<sup>", s, "</sup>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - JSValue a0 = exec->argument(0); - return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec), "\">", s, "</font>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - JSValue a0 = exec->argument(0); - - uint32_t smallInteger; - if (a0.getUInt32(smallInteger) && smallInteger <= 9) { - unsigned stringSize = s.length(); - unsigned bufferSize = 22 + stringSize; - UChar* buffer; - PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(bufferSize, buffer); - if (!impl) - return JSValue::encode(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.characters(), 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 JSValue::encode(jsNontrivialString(exec, impl)); - } - - return JSValue::encode(jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec), "\">", s, "</font>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - JSValue a0 = exec->argument(0); - return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec), "\">", s, "</a>")); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - UString s = thisValue.toThisString(exec); - JSValue a0 = exec->argument(0); - UString linkText = a0.toString(exec); - - unsigned linkTextSize = linkText.length(); - unsigned stringSize = s.length(); - unsigned bufferSize = 15 + linkTextSize + stringSize; - UChar* buffer; - PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(bufferSize, buffer); - if (!impl) - return JSValue::encode(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.characters(), linkTextSize * sizeof(UChar)); - buffer[9 + linkTextSize] = '"'; - buffer[10 + linkTextSize] = '>'; - memcpy(&buffer[11 + linkTextSize], s.characters(), stringSize * sizeof(UChar)); - buffer[11 + linkTextSize + stringSize] = '<'; - buffer[12 + linkTextSize + stringSize] = '/'; - buffer[13 + linkTextSize + stringSize] = 'a'; - buffer[14 + linkTextSize + stringSize] = '>'; - return JSValue::encode(jsNontrivialString(exec, impl)); -} - -enum { - TrimLeft = 1, - TrimRight = 2 -}; - -static inline bool isTrimWhitespace(UChar c) -{ - return isStrWhiteSpace(c) || c == 0x200b; -} - -static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind) -{ - if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible - return throwTypeError(exec); - UString str = thisValue.toThisString(exec); - unsigned left = 0; - if (trimKind & TrimLeft) { - while (left < str.length() && isTrimWhitespace(str[left])) - left++; - } - unsigned right = str.length(); - if (trimKind & TrimRight) { - while (right > left && isTrimWhitespace(str[right - 1])) - right--; - } - - // Don't gc allocate a new string if we don't have to. - if (left == 0 && right == str.length() && thisValue.isString()) - return thisValue; - - return jsString(exec, str.substringSharingImpl(left, right - left)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(trimString(exec, thisValue, TrimLeft | TrimRight)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(trimString(exec, thisValue, TrimLeft)); -} - -EncodedJSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec) -{ - JSValue thisValue = exec->hostThisValue(); - return JSValue::encode(trimString(exec, thisValue, TrimRight)); -} - - -} // namespace JSC diff --git a/JavaScriptCore/runtime/StringPrototype.h b/JavaScriptCore/runtime/StringPrototype.h deleted file mode 100644 index 4b0f88f..0000000 --- a/JavaScriptCore/runtime/StringPrototype.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef StringPrototype_h -#define StringPrototype_h - -#include "StringObject.h" - -namespace JSC { - - class ObjectPrototype; - - class StringPrototype : public StringObject { - public: - StringPrototype(ExecState*, JSGlobalObject*, NonNullPassRefPtr<Structure>); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - }; - -} // namespace JSC - -#endif // StringPrototype_h diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp deleted file mode 100644 index 0179eed..0000000 --- a/JavaScriptCore/runtime/Structure.cpp +++ /dev/null @@ -1,1270 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Structure.h" - -#include "Identifier.h" -#include "JSObject.h" -#include "JSPropertyNameIterator.h" -#include "Lookup.h" -#include "PropertyNameArray.h" -#include "StructureChain.h" -#include <wtf/RefCountedLeakCounter.h> -#include <wtf/RefPtr.h> - -#if ENABLE(JSC_MULTIPLE_THREADS) -#include <wtf/Threading.h> -#endif - -#define DUMP_STRUCTURE_ID_STATISTICS 0 - -#ifndef NDEBUG -#define DO_PROPERTYMAP_CONSTENCY_CHECK 0 -#else -#define DO_PROPERTYMAP_CONSTENCY_CHECK 0 -#endif - -using namespace std; -using namespace WTF; - -namespace JSC { - -// Choose a number for the following so that most property maps are smaller, -// but it's not going to blow out the stack to allocate this number of pointers. -static const int smallMapThreshold = 1024; - -// The point at which the function call overhead of the qsort implementation -// becomes small compared to the inefficiency of insertion sort. -static const unsigned tinyMapThreshold = 20; - -static const unsigned newTableSize = 16; - -#ifndef NDEBUG -static WTF::RefCountedLeakCounter structureCounter("Structure"); - -#if ENABLE(JSC_MULTIPLE_THREADS) -static Mutex& ignoreSetMutex = *(new Mutex); -#endif - -static bool shouldIgnoreLeaks; -static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>); -#endif - -#if DUMP_STRUCTURE_ID_STATISTICS -static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>); -#endif - -static int comparePropertyMapEntryIndices(const void* a, const void* b); - -inline void Structure::setTransitionTable(TransitionTable* table) -{ - ASSERT(m_isUsingSingleSlot); -#ifndef NDEBUG - setSingleTransition(0); -#endif - m_isUsingSingleSlot = false; - m_transitions.m_table = table; - // This implicitly clears the flag that indicates we're using a single transition - ASSERT(!m_isUsingSingleSlot); -} - -// The contains and get methods accept imprecise matches, so if an unspecialised transition exists -// for the given key they will consider that transition to be a match. If a specialised transition -// exists and it matches the provided specificValue, get will return the specific transition. -inline bool Structure::transitionTableContains(const StructureTransitionTableHash::Key& key, JSCell* specificValue) -{ - if (m_isUsingSingleSlot) { - Structure* existingTransition = singleTransition(); - return existingTransition && existingTransition->m_nameInPrevious.get() == key.first - && existingTransition->m_attributesInPrevious == key.second - && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0); - } - TransitionTable::iterator find = transitionTable()->find(key); - if (find == transitionTable()->end()) - return false; - - return find->second.first || find->second.second->transitionedFor(specificValue); -} - -inline Structure* Structure::transitionTableGet(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const -{ - if (m_isUsingSingleSlot) { - Structure* existingTransition = singleTransition(); - if (existingTransition && existingTransition->m_nameInPrevious.get() == key.first - && existingTransition->m_attributesInPrevious == key.second - && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0)) - return existingTransition; - return 0; - } - - Transition transition = transitionTable()->get(key); - if (transition.second && transition.second->transitionedFor(specificValue)) - return transition.second; - return transition.first; -} - -inline bool Structure::transitionTableHasTransition(const StructureTransitionTableHash::Key& key) const -{ - if (m_isUsingSingleSlot) { - Structure* transition = singleTransition(); - return transition && transition->m_nameInPrevious == key.first - && transition->m_attributesInPrevious == key.second; - } - return transitionTable()->contains(key); -} - -inline void Structure::transitionTableRemove(const StructureTransitionTableHash::Key& key, JSCell* specificValue) -{ - if (m_isUsingSingleSlot) { - ASSERT(transitionTableContains(key, specificValue)); - setSingleTransition(0); - return; - } - TransitionTable::iterator find = transitionTable()->find(key); - if (!specificValue) - find->second.first = 0; - else - find->second.second = 0; - if (!find->second.first && !find->second.second) - transitionTable()->remove(find); -} - -inline void Structure::transitionTableAdd(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue) -{ - if (m_isUsingSingleSlot) { - if (!singleTransition()) { - setSingleTransition(structure); - return; - } - Structure* existingTransition = singleTransition(); - TransitionTable* transitionTable = new TransitionTable; - setTransitionTable(transitionTable); - if (existingTransition) - transitionTableAdd(std::make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious); - } - if (!specificValue) { - TransitionTable::iterator find = transitionTable()->find(key); - if (find == transitionTable()->end()) - transitionTable()->add(key, Transition(structure, static_cast<Structure*>(0))); - else - find->second.first = structure; - } else { - // If we're adding a transition to a specific value, then there cannot be - // an existing transition - ASSERT(!transitionTable()->contains(key)); - transitionTable()->add(key, Transition(static_cast<Structure*>(0), structure)); - } -} - -void Structure::dumpStatistics() -{ -#if DUMP_STRUCTURE_ID_STATISTICS - unsigned numberLeaf = 0; - unsigned numberUsingSingleSlot = 0; - unsigned numberSingletons = 0; - unsigned numberWithPropertyMaps = 0; - unsigned totalPropertyMapsSize = 0; - - HashSet<Structure*>::const_iterator end = liveStructureSet.end(); - for (HashSet<Structure*>::const_iterator it = liveStructureSet.begin(); it != end; ++it) { - Structure* structure = *it; - if (structure->m_usingSingleTransitionSlot) { - if (!structure->m_transitions.singleTransition) - ++numberLeaf; - else - ++numberUsingSingleSlot; - - if (!structure->m_previous && !structure->m_transitions.singleTransition) - ++numberSingletons; - } - - if (structure->m_propertyTable) { - ++numberWithPropertyMaps; - totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structure->m_propertyTable->size); - if (structure->m_propertyTable->deletedOffsets) - totalPropertyMapsSize += (structure->m_propertyTable->deletedOffsets->capacity() * sizeof(unsigned)); - } - } - - printf("Number of live Structures: %d\n", liveStructureSet.size()); - printf("Number of Structures using the single item optimization for transition map: %d\n", numberUsingSingleSlot); - printf("Number of Structures that are leaf nodes: %d\n", numberLeaf); - printf("Number of Structures that singletons: %d\n", numberSingletons); - printf("Number of Structures with PropertyMaps: %d\n", numberWithPropertyMaps); - - printf("Size of a single Structures: %d\n", static_cast<unsigned>(sizeof(Structure))); - printf("Size of sum of all property maps: %d\n", totalPropertyMapsSize); - printf("Size of average of all property maps: %f\n", static_cast<double>(totalPropertyMapsSize) / static_cast<double>(liveStructureSet.size())); -#else - printf("Dumping Structure statistics is not enabled.\n"); -#endif -} - -Structure::Structure(JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount) - : m_typeInfo(typeInfo) - , m_prototype(prototype) - , m_specificValueInPrevious(0) - , m_propertyTable(0) - , m_propertyStorageCapacity(JSObject::inlineStorageCapacity) - , m_offset(noOffset) - , m_dictionaryKind(NoneDictionaryKind) - , m_isPinnedPropertyTable(false) - , m_hasGetterSetterProperties(false) - , m_hasNonEnumerableProperties(false) - , m_attributesInPrevious(0) - , m_specificFunctionThrashCount(0) - , m_anonymousSlotCount(anonymousSlotCount) - , m_isUsingSingleSlot(true) -{ - m_transitions.m_singleTransition = 0; - - ASSERT(m_prototype); - ASSERT(m_prototype.isObject() || m_prototype.isNull()); - -#ifndef NDEBUG -#if ENABLE(JSC_MULTIPLE_THREADS) - MutexLocker protect(ignoreSetMutex); -#endif - if (shouldIgnoreLeaks) - ignoreSet.add(this); - else - structureCounter.increment(); -#endif - -#if DUMP_STRUCTURE_ID_STATISTICS - liveStructureSet.add(this); -#endif -} - -Structure::~Structure() -{ - if (m_previous) { - ASSERT(m_nameInPrevious); - m_previous->transitionTableRemove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious); - - } - ASSERT(!m_enumerationCache.hasDeadObject()); - - if (m_propertyTable) { - unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; - for (unsigned i = 1; i <= entryCount; i++) { - if (StringImpl* key = m_propertyTable->entries()[i].key) - key->deref(); - } - - delete m_propertyTable->deletedOffsets; - fastFree(m_propertyTable); - } - - if (!m_isUsingSingleSlot) - delete transitionTable(); - -#ifndef NDEBUG -#if ENABLE(JSC_MULTIPLE_THREADS) - MutexLocker protect(ignoreSetMutex); -#endif - HashSet<Structure*>::iterator it = ignoreSet.find(this); - if (it != ignoreSet.end()) - ignoreSet.remove(it); - else - structureCounter.decrement(); -#endif - -#if DUMP_STRUCTURE_ID_STATISTICS - liveStructureSet.remove(this); -#endif -} - -void Structure::startIgnoringLeaks() -{ -#ifndef NDEBUG - shouldIgnoreLeaks = true; -#endif -} - -void Structure::stopIgnoringLeaks() -{ -#ifndef NDEBUG - shouldIgnoreLeaks = false; -#endif -} - -static bool isPowerOf2(unsigned v) -{ - // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html - - return !(v & (v - 1)) && v; -} - -static unsigned nextPowerOf2(unsigned v) -{ - // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html - // Devised by Sean Anderson, Sepember 14, 2001 - - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - - return v; -} - -static unsigned sizeForKeyCount(size_t keyCount) -{ - if (keyCount == notFound) - return newTableSize; - - if (keyCount < 8) - return newTableSize; - - if (isPowerOf2(keyCount)) - return keyCount * 4; - - return nextPowerOf2(keyCount) * 2; -} - -void Structure::materializePropertyMap() -{ - ASSERT(!m_propertyTable); - - Vector<Structure*, 8> structures; - structures.append(this); - - Structure* structure = this; - - // Search for the last Structure with a property table. - while ((structure = structure->previousID())) { - if (structure->m_isPinnedPropertyTable) { - ASSERT(structure->m_propertyTable); - ASSERT(!structure->m_previous); - - m_propertyTable = structure->copyPropertyTable(); - break; - } - - structures.append(structure); - } - - if (!m_propertyTable) - createPropertyMapHashTable(sizeForKeyCount(m_offset + 1)); - else { - if (sizeForKeyCount(m_offset + 1) > m_propertyTable->size) - rehashPropertyMapHashTable(sizeForKeyCount(m_offset + 1)); // This could be made more efficient by combining with the copy above. - } - - for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) { - structure = structures[i]; - structure->m_nameInPrevious->ref(); - PropertyMapEntry entry(structure->m_nameInPrevious.get(), m_anonymousSlotCount + structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed); - insertIntoPropertyMapHashTable(entry); - } -} - -void Structure::growPropertyStorageCapacity() -{ - if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity) - m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity; - else - m_propertyStorageCapacity *= 2; -} - -void Structure::despecifyDictionaryFunction(const Identifier& propertyName) -{ - const StringImpl* rep = propertyName.impl(); - - materializePropertyMapIfNecessary(); - - ASSERT(isDictionary()); - ASSERT(m_propertyTable); - - unsigned i = rep->existingHash(); - -#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->existingHash()); - - 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->isDictionary()); - ASSERT(structure->typeInfo().type() == ObjectType); - - if (Structure* existingTransition = structure->transitionTableGet(make_pair(propertyName.impl(), attributes), specificValue)) { - ASSERT(existingTransition->m_offset != noOffset); - offset = existingTransition->m_offset + existingTransition->m_anonymousSlotCount; - ASSERT(offset >= structure->m_anonymousSlotCount); - ASSERT(structure->m_anonymousSlotCount == existingTransition->m_anonymousSlotCount); - return existingTransition; - } - - return 0; -} - -PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) -{ - ASSERT(!structure->isDictionary()); - ASSERT(structure->typeInfo().type() == ObjectType); - ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); - - if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) - specificValue = 0; - - if (structure->transitionCount() > s_maxTransitionLength) { - RefPtr<Structure> transition = toCacheableDictionaryTransition(structure); - ASSERT(structure != transition); - offset = transition->put(propertyName, attributes, specificValue); - ASSERT(offset >= structure->m_anonymousSlotCount); - ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount); - if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) - transition->growPropertyStorageCapacity(); - return transition.release(); - } - - RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo(), structure->anonymousSlotCount()); - - transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; - transition->m_previous = structure; - transition->m_nameInPrevious = propertyName.impl(); - transition->m_attributesInPrevious = attributes; - transition->m_specificValueInPrevious = specificValue; - transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; - transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; - transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; - - if (structure->m_propertyTable) { - if (structure->m_isPinnedPropertyTable) - transition->m_propertyTable = structure->copyPropertyTable(); - else { - transition->m_propertyTable = structure->m_propertyTable; - structure->m_propertyTable = 0; - } - } else { - if (structure->m_previous) - transition->materializePropertyMap(); - else - transition->createPropertyMapHashTable(); - } - - offset = transition->put(propertyName, attributes, specificValue); - ASSERT(offset >= structure->m_anonymousSlotCount); - ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount); - if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) - transition->growPropertyStorageCapacity(); - - transition->m_offset = offset - structure->m_anonymousSlotCount; - ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); - structure->transitionTableAdd(make_pair(propertyName.impl(), attributes), transition.get(), specificValue); - return transition.release(); -} - -PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset) -{ - ASSERT(!structure->isUncacheableDictionary()); - - RefPtr<Structure> transition = toUncacheableDictionaryTransition(structure); - - offset = transition->remove(propertyName); - ASSERT(offset >= structure->m_anonymousSlotCount); - ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount); - - return transition.release(); -} - -PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValue prototype) -{ - RefPtr<Structure> transition = create(prototype, structure->typeInfo(), structure->anonymousSlotCount()); - - transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; - transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; - transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; - - // Don't set m_offset, as one can not transition to this. - - structure->materializePropertyMapIfNecessary(); - transition->m_propertyTable = structure->copyPropertyTable(); - transition->m_isPinnedPropertyTable = true; - - ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); - return transition.release(); -} - -PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction) -{ - ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount); - RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo(), structure->anonymousSlotCount()); - - transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; - transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; - transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount + 1; - - // Don't set m_offset, as one can not transition to this. - - structure->materializePropertyMapIfNecessary(); - transition->m_propertyTable = structure->copyPropertyTable(); - transition->m_isPinnedPropertyTable = true; - - if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) - transition->despecifyAllFunctions(); - else { - bool removed = transition->despecifyFunction(replaceFunction); - ASSERT_UNUSED(removed, removed); - } - - ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); - return transition.release(); -} - -PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) -{ - RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo(), structure->anonymousSlotCount()); - transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; - transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties; - transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; - transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; - - // Don't set m_offset, as one can not transition to this. - - structure->materializePropertyMapIfNecessary(); - transition->m_propertyTable = structure->copyPropertyTable(); - transition->m_isPinnedPropertyTable = true; - - ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); - return transition.release(); -} - -PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind) -{ - ASSERT(!structure->isUncacheableDictionary()); - - RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo(), structure->anonymousSlotCount()); - transition->m_dictionaryKind = kind; - transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; - transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; - transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; - - structure->materializePropertyMapIfNecessary(); - transition->m_propertyTable = structure->copyPropertyTable(); - transition->m_isPinnedPropertyTable = true; - - ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); - return transition.release(); -} - -PassRefPtr<Structure> Structure::toCacheableDictionaryTransition(Structure* structure) -{ - return toDictionaryTransition(structure, CachedDictionaryKind); -} - -PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* structure) -{ - return toDictionaryTransition(structure, UncachedDictionaryKind); -} - -PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object) -{ - ASSERT(isDictionary()); - if (isUncacheableDictionary()) { - ASSERT(m_propertyTable); - Vector<PropertyMapEntry*> sortedPropertyEntries(m_propertyTable->keyCount); - PropertyMapEntry** p = sortedPropertyEntries.data(); - unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; - for (unsigned i = 1; i <= entryCount; i++) { - if (m_propertyTable->entries()[i].key) - *p++ = &m_propertyTable->entries()[i]; - } - size_t propertyCount = p - sortedPropertyEntries.data(); - qsort(sortedPropertyEntries.data(), propertyCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices); - sortedPropertyEntries.resize(propertyCount); - - // We now have the properties currently defined on this object - // in the order that they are expected to be in, but we need to - // reorder the storage, so we have to copy the current values out - Vector<JSValue> values(propertyCount); - unsigned anonymousSlotCount = m_anonymousSlotCount; - for (unsigned i = 0; i < propertyCount; i++) { - PropertyMapEntry* entry = sortedPropertyEntries[i]; - values[i] = object->getDirectOffset(entry->offset); - // Update property table to have the new property offsets - entry->offset = anonymousSlotCount + i; - entry->index = i; - } - - // Copy the original property values into their final locations - for (unsigned i = 0; i < propertyCount; i++) - object->putDirectOffset(anonymousSlotCount + i, values[i]); - - if (m_propertyTable->deletedOffsets) { - delete m_propertyTable->deletedOffsets; - m_propertyTable->deletedOffsets = 0; - } - } - - m_dictionaryKind = NoneDictionaryKind; - return this; -} - -size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) -{ - ASSERT(!m_enumerationCache); - - if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) - specificValue = 0; - - materializePropertyMapIfNecessary(); - - m_isPinnedPropertyTable = true; - - size_t offset = put(propertyName, attributes, specificValue); - ASSERT(offset >= m_anonymousSlotCount); - if (propertyStorageSize() > propertyStorageCapacity()) - growPropertyStorageCapacity(); - return offset; -} - -size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName) -{ - ASSERT(isUncacheableDictionary()); - ASSERT(!m_enumerationCache); - - materializePropertyMapIfNecessary(); - - m_isPinnedPropertyTable = true; - size_t offset = remove(propertyName); - ASSERT(offset >= m_anonymousSlotCount); - return offset; -} - -#if DUMP_PROPERTYMAP_STATS - -static int numProbes; -static int numCollisions; -static int numRehashes; -static int numRemoves; - -struct PropertyMapStatisticsExitLogger { - ~PropertyMapStatisticsExitLogger(); -}; - -static PropertyMapStatisticsExitLogger logger; - -PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger() -{ - printf("\nJSC::PropertyMap statistics\n\n"); - printf("%d probes\n", numProbes); - printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes); - printf("%d rehashes\n", numRehashes); - printf("%d removes\n", numRemoves); -} - -#endif - -static const unsigned deletedSentinelIndex = 1; - -#if !DO_PROPERTYMAP_CONSTENCY_CHECK - -inline void Structure::checkConsistency() -{ -} - -#endif - -PropertyMapHashTable* Structure::copyPropertyTable() -{ - if (!m_propertyTable) - return 0; - - size_t tableSize = PropertyMapHashTable::allocationSize(m_propertyTable->size); - PropertyMapHashTable* newTable = static_cast<PropertyMapHashTable*>(fastMalloc(tableSize)); - memcpy(newTable, m_propertyTable, tableSize); - - unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; - for (unsigned i = 1; i <= entryCount; ++i) { - if (StringImpl* key = newTable->entries()[i].key) - key->ref(); - } - - // Copy the deletedOffsets vector. - if (m_propertyTable->deletedOffsets) - newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets); - - return newTable; -} - -size_t Structure::get(const StringImpl* rep, unsigned& attributes, JSCell*& specificValue) -{ - materializePropertyMapIfNecessary(); - if (!m_propertyTable) - return notFound; - - unsigned i = rep->existingHash(); - -#if DUMP_PROPERTYMAP_STATS - ++numProbes; -#endif - - unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - return notFound; - - if (rep == m_propertyTable->entries()[entryIndex - 1].key) { - attributes = m_propertyTable->entries()[entryIndex - 1].attributes; - specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue; - ASSERT(m_propertyTable->entries()[entryIndex - 1].offset >= m_anonymousSlotCount); - return m_propertyTable->entries()[entryIndex - 1].offset; - } - -#if DUMP_PROPERTYMAP_STATS - ++numCollisions; -#endif - - unsigned k = 1 | doubleHash(rep->existingHash()); - - while (1) { - i += k; - -#if DUMP_PROPERTYMAP_STATS - ++numRehashes; -#endif - - entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - return notFound; - - if (rep == m_propertyTable->entries()[entryIndex - 1].key) { - attributes = m_propertyTable->entries()[entryIndex - 1].attributes; - specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue; - ASSERT(m_propertyTable->entries()[entryIndex - 1].offset >= m_anonymousSlotCount); - return m_propertyTable->entries()[entryIndex - 1].offset; - } - } -} - -bool Structure::despecifyFunction(const Identifier& propertyName) -{ - ASSERT(!propertyName.isNull()); - - materializePropertyMapIfNecessary(); - if (!m_propertyTable) - return false; - - StringImpl* rep = propertyName.impl(); - - unsigned i = rep->existingHash(); - -#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->existingHash()); - - 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; - } - } -} - -void Structure::despecifyAllFunctions() -{ - materializePropertyMapIfNecessary(); - if (!m_propertyTable) - return; - - unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; - for (unsigned i = 1; i <= entryCount; ++i) - m_propertyTable->entries()[i].specificValue = 0; -} - -size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) -{ - ASSERT(!propertyName.isNull()); - ASSERT(get(propertyName) == notFound); - - checkConsistency(); - - if (attributes & DontEnum) - m_hasNonEnumerableProperties = true; - - StringImpl* rep = propertyName.impl(); - - if (!m_propertyTable) - createPropertyMapHashTable(); - - // FIXME: Consider a fast case for tables with no deleted sentinels. - - unsigned i = rep->existingHash(); - unsigned k = 0; - bool foundDeletedElement = false; - unsigned deletedElementIndex = 0; // initialize to make the compiler happy - -#if DUMP_PROPERTYMAP_STATS - ++numProbes; -#endif - - while (1) { - unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - break; - - if (entryIndex == deletedSentinelIndex) { - // If we find a deleted-element sentinel, remember it for use later. - if (!foundDeletedElement) { - foundDeletedElement = true; - deletedElementIndex = i; - } - } - - if (k == 0) { - k = 1 | doubleHash(rep->existingHash()); -#if DUMP_PROPERTYMAP_STATS - ++numCollisions; -#endif - } - - i += k; - -#if DUMP_PROPERTYMAP_STATS - ++numRehashes; -#endif - } - - // Figure out which entry to use. - unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2; - if (foundDeletedElement) { - i = deletedElementIndex; - --m_propertyTable->deletedSentinelCount; - - // Since we're not making the table bigger, we can't use the entry one past - // the end that we were planning on using, so search backwards for the empty - // slot that we can use. We know it will be there because we did at least one - // deletion in the past that left an entry empty. - while (m_propertyTable->entries()[--entryIndex - 1].key) { } - } - - // Create a new hash table entry. - m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex; - - // Create a new hash table entry. - rep->ref(); - m_propertyTable->entries()[entryIndex - 1].key = rep; - m_propertyTable->entries()[entryIndex - 1].attributes = attributes; - m_propertyTable->entries()[entryIndex - 1].specificValue = specificValue; - m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed; - - unsigned newOffset; - if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) { - newOffset = m_propertyTable->deletedOffsets->last(); - m_propertyTable->deletedOffsets->removeLast(); - } else - newOffset = m_propertyTable->keyCount + m_anonymousSlotCount; - m_propertyTable->entries()[entryIndex - 1].offset = newOffset; - - ASSERT(newOffset >= m_anonymousSlotCount); - ++m_propertyTable->keyCount; - - if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size) - expandPropertyMapHashTable(); - - checkConsistency(); - return newOffset; -} - -bool Structure::hasTransition(StringImpl* rep, unsigned attributes) -{ - return transitionTableHasTransition(make_pair(rep, attributes)); -} - -size_t Structure::remove(const Identifier& propertyName) -{ - ASSERT(!propertyName.isNull()); - - checkConsistency(); - - StringImpl* rep = propertyName.impl(); - - if (!m_propertyTable) - return notFound; - -#if DUMP_PROPERTYMAP_STATS - ++numProbes; - ++numRemoves; -#endif - - // Find the thing to remove. - unsigned i = rep->existingHash(); - unsigned k = 0; - unsigned entryIndex; - StringImpl* key = 0; - while (1) { - entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - return notFound; - - key = m_propertyTable->entries()[entryIndex - 1].key; - if (rep == key) - break; - - if (k == 0) { - k = 1 | doubleHash(rep->existingHash()); -#if DUMP_PROPERTYMAP_STATS - ++numCollisions; -#endif - } - - i += k; - -#if DUMP_PROPERTYMAP_STATS - ++numRehashes; -#endif - } - - // Replace this one element with the deleted sentinel. Also clear out - // the entry so we can iterate all the entries as needed. - m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex; - - size_t offset = m_propertyTable->entries()[entryIndex - 1].offset; - ASSERT(offset >= m_anonymousSlotCount); - - key->deref(); - m_propertyTable->entries()[entryIndex - 1].key = 0; - m_propertyTable->entries()[entryIndex - 1].attributes = 0; - m_propertyTable->entries()[entryIndex - 1].specificValue = 0; - m_propertyTable->entries()[entryIndex - 1].offset = 0; - - if (!m_propertyTable->deletedOffsets) - m_propertyTable->deletedOffsets = new Vector<unsigned>; - m_propertyTable->deletedOffsets->append(offset); - - ASSERT(m_propertyTable->keyCount >= 1); - --m_propertyTable->keyCount; - ++m_propertyTable->deletedSentinelCount; - - if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size) - rehashPropertyMapHashTable(); - - checkConsistency(); - return offset; -} - -void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry) -{ - ASSERT(m_propertyTable); - ASSERT(entry.offset >= m_anonymousSlotCount); - unsigned i = entry.key->existingHash(); - unsigned k = 0; - -#if DUMP_PROPERTYMAP_STATS - ++numProbes; -#endif - - while (1) { - unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - break; - - if (k == 0) { - k = 1 | doubleHash(entry.key->existingHash()); -#if DUMP_PROPERTYMAP_STATS - ++numCollisions; -#endif - } - - i += k; - -#if DUMP_PROPERTYMAP_STATS - ++numRehashes; -#endif - } - - unsigned entryIndex = m_propertyTable->keyCount + 2; - m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex; - m_propertyTable->entries()[entryIndex - 1] = entry; - - ++m_propertyTable->keyCount; -} - -void Structure::createPropertyMapHashTable() -{ - ASSERT(sizeForKeyCount(7) == newTableSize); - createPropertyMapHashTable(newTableSize); -} - -void Structure::createPropertyMapHashTable(unsigned newTableSize) -{ - ASSERT(!m_propertyTable); - ASSERT(isPowerOf2(newTableSize)); - - checkConsistency(); - - m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize))); - m_propertyTable->size = newTableSize; - m_propertyTable->sizeMask = newTableSize - 1; - - checkConsistency(); -} - -void Structure::expandPropertyMapHashTable() -{ - ASSERT(m_propertyTable); - rehashPropertyMapHashTable(m_propertyTable->size * 2); -} - -void Structure::rehashPropertyMapHashTable() -{ - ASSERT(m_propertyTable); - ASSERT(m_propertyTable->size); - rehashPropertyMapHashTable(m_propertyTable->size); -} - -void Structure::rehashPropertyMapHashTable(unsigned newTableSize) -{ - ASSERT(m_propertyTable); - ASSERT(isPowerOf2(newTableSize)); - - checkConsistency(); - - PropertyMapHashTable* oldTable = m_propertyTable; - - m_propertyTable = static_cast<PropertyMapHashTable*>(fastZeroedMalloc(PropertyMapHashTable::allocationSize(newTableSize))); - m_propertyTable->size = newTableSize; - m_propertyTable->sizeMask = newTableSize - 1; - - unsigned lastIndexUsed = 0; - unsigned entryCount = oldTable->keyCount + oldTable->deletedSentinelCount; - for (unsigned i = 1; i <= entryCount; ++i) { - if (oldTable->entries()[i].key) { - lastIndexUsed = max(oldTable->entries()[i].index, lastIndexUsed); - insertIntoPropertyMapHashTable(oldTable->entries()[i]); - } - } - m_propertyTable->lastIndexUsed = lastIndexUsed; - m_propertyTable->deletedOffsets = oldTable->deletedOffsets; - - fastFree(oldTable); - - checkConsistency(); -} - -int comparePropertyMapEntryIndices(const void* a, const void* b) -{ - unsigned ia = static_cast<PropertyMapEntry* const*>(a)[0]->index; - unsigned ib = static_cast<PropertyMapEntry* const*>(b)[0]->index; - if (ia < ib) - return -1; - if (ia > ib) - return +1; - return 0; -} - -void Structure::getPropertyNames(PropertyNameArray& propertyNames, EnumerationMode mode) -{ - materializePropertyMapIfNecessary(); - if (!m_propertyTable) - return; - - if (m_propertyTable->keyCount < tinyMapThreshold) { - PropertyMapEntry* a[tinyMapThreshold]; - int i = 0; - unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; - for (unsigned k = 1; k <= entryCount; k++) { - ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[k].attributes & DontEnum)); - if (m_propertyTable->entries()[k].key && (!(m_propertyTable->entries()[k].attributes & DontEnum) || (mode == IncludeDontEnumProperties))) { - PropertyMapEntry* value = &m_propertyTable->entries()[k]; - int j; - for (j = i - 1; j >= 0 && a[j]->index > value->index; --j) - a[j + 1] = a[j]; - a[j + 1] = value; - ++i; - } - } - if (!propertyNames.size()) { - for (int k = 0; k < i; ++k) - propertyNames.addKnownUnique(a[k]->key); - } else { - for (int k = 0; k < i; ++k) - propertyNames.add(a[k]->key); - } - - return; - } - - // Allocate a buffer to use to sort the keys. - Vector<PropertyMapEntry*, smallMapThreshold> sortedEnumerables(m_propertyTable->keyCount); - - // Get pointers to the enumerable entries in the buffer. - PropertyMapEntry** p = sortedEnumerables.data(); - unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; - for (unsigned i = 1; i <= entryCount; i++) { - if (m_propertyTable->entries()[i].key && (!(m_propertyTable->entries()[i].attributes & DontEnum) || (mode == IncludeDontEnumProperties))) - *p++ = &m_propertyTable->entries()[i]; - } - - size_t enumerableCount = p - sortedEnumerables.data(); - // Sort the entries by index. - qsort(sortedEnumerables.data(), enumerableCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices); - sortedEnumerables.resize(enumerableCount); - - // Put the keys of the sorted entries into the list. - if (!propertyNames.size()) { - for (size_t i = 0; i < sortedEnumerables.size(); ++i) - propertyNames.addKnownUnique(sortedEnumerables[i]->key); - } else { - for (size_t i = 0; i < sortedEnumerables.size(); ++i) - propertyNames.add(sortedEnumerables[i]->key); - } -} - -#if DO_PROPERTYMAP_CONSTENCY_CHECK - -void Structure::checkConsistency() -{ - if (!m_propertyTable) - return; - - ASSERT(m_propertyTable->size >= newTableSize); - ASSERT(m_propertyTable->sizeMask); - ASSERT(m_propertyTable->size == m_propertyTable->sizeMask + 1); - ASSERT(!(m_propertyTable->size & m_propertyTable->sizeMask)); - - ASSERT(m_propertyTable->keyCount <= m_propertyTable->size / 2); - ASSERT(m_propertyTable->deletedSentinelCount <= m_propertyTable->size / 4); - - ASSERT(m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount <= m_propertyTable->size / 2); - - unsigned indexCount = 0; - unsigned deletedIndexCount = 0; - for (unsigned a = 0; a != m_propertyTable->size; ++a) { - unsigned entryIndex = m_propertyTable->entryIndices[a]; - if (entryIndex == emptyEntryIndex) - continue; - if (entryIndex == deletedSentinelIndex) { - ++deletedIndexCount; - continue; - } - ASSERT(entryIndex > deletedSentinelIndex); - ASSERT(entryIndex - 1 <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount); - ++indexCount; - - for (unsigned b = a + 1; b != m_propertyTable->size; ++b) - ASSERT(m_propertyTable->entryIndices[b] != entryIndex); - } - ASSERT(indexCount == m_propertyTable->keyCount); - ASSERT(deletedIndexCount == m_propertyTable->deletedSentinelCount); - - ASSERT(m_propertyTable->entries()[0].key == 0); - - unsigned nonEmptyEntryCount = 0; - for (unsigned c = 1; c <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; ++c) { - ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[c].attributes & DontEnum)); - StringImpl* rep = m_propertyTable->entries()[c].key; - ASSERT(m_propertyTable->entries()[c].offset >= m_anonymousSlotCount); - if (!rep) - continue; - ++nonEmptyEntryCount; - unsigned i = rep->existingHash(); - unsigned k = 0; - unsigned entryIndex; - while (1) { - entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - ASSERT(entryIndex != emptyEntryIndex); - if (rep == m_propertyTable->entries()[entryIndex - 1].key) - break; - if (k == 0) - k = 1 | doubleHash(rep->existingHash()); - i += k; - } - ASSERT(entryIndex == c + 1); - } - - ASSERT(nonEmptyEntryCount == m_propertyTable->keyCount); -} - -#endif // DO_PROPERTYMAP_CONSTENCY_CHECK - -} // namespace JSC diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h deleted file mode 100644 index f480051..0000000 --- a/JavaScriptCore/runtime/Structure.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef Structure_h -#define Structure_h - -#include "Identifier.h" -#include "JSType.h" -#include "JSValue.h" -#include "PropertyMapHashTable.h" -#include "PropertyNameArray.h" -#include "Protect.h" -#include "StructureChain.h" -#include "StructureTransitionTable.h" -#include "JSTypeInfo.h" -#include "UString.h" -#include "WeakGCPtr.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> - -#ifndef NDEBUG -#define DUMP_PROPERTYMAP_STATS 0 -#else -#define DUMP_PROPERTYMAP_STATS 0 -#endif - -namespace JSC { - - class MarkStack; - class PropertyNameArray; - class PropertyNameArrayData; - - enum EnumerationMode { - ExcludeDontEnumProperties, - IncludeDontEnumProperties - }; - - class Structure : public RefCounted<Structure> { - public: - friend class JIT; - friend class StructureTransitionTable; - static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount) - { - return adoptRef(new Structure(prototype, typeInfo, anonymousSlotCount)); - } - - static void startIgnoringLeaks(); - static void stopIgnoringLeaks(); - - static void dumpStatistics(); - - static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); - static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); - static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset); - static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype); - static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&); - static PassRefPtr<Structure> getterSetterTransition(Structure*); - static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*); - static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*); - - PassRefPtr<Structure> flattenDictionaryStructure(JSObject*); - - ~Structure(); - - // These should be used with caution. - size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); - size_t removePropertyWithoutTransition(const Identifier& propertyName); - void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; } - - bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; } - bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; } - - const TypeInfo& typeInfo() const { return m_typeInfo; } - - JSValue storedPrototype() const { return m_prototype; } - JSValue prototypeForLookup(ExecState*) const; - StructureChain* prototypeChain(ExecState*) const; - - Structure* previousID() const { return m_previous.get(); } - - void growPropertyStorageCapacity(); - unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; } - unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : static_cast<unsigned>(m_offset + 1)); } - bool isUsingInlineStorage() const; - - size_t get(const Identifier& propertyName); - size_t get(const StringImpl* rep, unsigned& attributes, JSCell*& specificValue); - size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue) - { - ASSERT(!propertyName.isNull()); - return get(propertyName.impl(), attributes, specificValue); - } - bool transitionedFor(const JSCell* specificValue) - { - return m_specificValueInPrevious == specificValue; - } - bool hasTransition(StringImpl*, unsigned attributes); - bool hasTransition(const Identifier& propertyName, unsigned attributes) - { - return hasTransition(propertyName.impl(), attributes); - } - - bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } - void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; } - - bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; } - - bool hasAnonymousSlots() const { return !!m_anonymousSlotCount; } - unsigned anonymousSlotCount() const { return m_anonymousSlotCount; } - - bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; } - - void despecifyDictionaryFunction(const Identifier& propertyName); - void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; } - - void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. - void clearEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. - JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h. - void getPropertyNames(PropertyNameArray&, EnumerationMode mode); - - private: - - Structure(JSValue prototype, const TypeInfo&, unsigned anonymousSlotCount); - - typedef enum { - NoneDictionaryKind = 0, - CachedDictionaryKind = 1, - UncachedDictionaryKind = 2 - } DictionaryKind; - static PassRefPtr<Structure> toDictionaryTransition(Structure*, DictionaryKind); - - size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); - size_t remove(const Identifier& propertyName); - - void expandPropertyMapHashTable(); - void rehashPropertyMapHashTable(); - void rehashPropertyMapHashTable(unsigned newTableSize); - void createPropertyMapHashTable(); - void createPropertyMapHashTable(unsigned newTableSize); - void insertIntoPropertyMapHashTable(const PropertyMapEntry&); - void checkConsistency(); - - bool despecifyFunction(const Identifier&); - void despecifyAllFunctions(); - - PropertyMapHashTable* copyPropertyTable(); - void materializePropertyMap(); - void materializePropertyMapIfNecessary() - { - if (m_propertyTable || !m_previous) - return; - materializePropertyMap(); - } - - 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; - } - - typedef std::pair<Structure*, Structure*> Transition; - typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable; - - inline bool transitionTableContains(const StructureTransitionTableHash::Key& key, JSCell* specificValue); - inline void transitionTableRemove(const StructureTransitionTableHash::Key& key, JSCell* specificValue); - inline void transitionTableAdd(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue); - inline bool transitionTableHasTransition(const StructureTransitionTableHash::Key& key) const; - inline Structure* transitionTableGet(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const; - - TransitionTable* transitionTable() const { ASSERT(!m_isUsingSingleSlot); return m_transitions.m_table; } - inline void setTransitionTable(TransitionTable* table); - Structure* singleTransition() const { ASSERT(m_isUsingSingleSlot); return m_transitions.m_singleTransition; } - void setSingleTransition(Structure* structure) { ASSERT(m_isUsingSingleSlot); m_transitions.m_singleTransition = structure; } - - bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const; - - static const unsigned emptyEntryIndex = 0; - - static const signed char s_maxTransitionLength = 64; - - static const signed char noOffset = -1; - - static const unsigned maxSpecificFunctionThrashCount = 3; - - TypeInfo m_typeInfo; - - JSValue m_prototype; - mutable RefPtr<StructureChain> m_cachedPrototypeChain; - - RefPtr<Structure> m_previous; - RefPtr<StringImpl> m_nameInPrevious; - JSCell* m_specificValueInPrevious; - - // 'm_isUsingSingleSlot' indicates whether we are using the single transition optimisation. - union { - TransitionTable* m_table; - Structure* m_singleTransition; - } m_transitions; - - WeakGCPtr<JSPropertyNameIterator> m_enumerationCache; - - PropertyMapHashTable* m_propertyTable; - - uint32_t m_propertyStorageCapacity; - - // m_offset does not account for anonymous slots - signed char m_offset; - - unsigned m_dictionaryKind : 2; - bool m_isPinnedPropertyTable : 1; - bool m_hasGetterSetterProperties : 1; - bool m_hasNonEnumerableProperties : 1; -#if COMPILER(WINSCW) - // Workaround for Symbian WINSCW compiler that cannot resolve unsigned type of the declared - // bitfield, when used as argument in make_pair() function calls in structure.ccp. - // This bitfield optimization is insignificant for the Symbian emulator target. - unsigned m_attributesInPrevious; -#else - unsigned m_attributesInPrevious : 7; -#endif - unsigned m_specificFunctionThrashCount : 2; - unsigned m_anonymousSlotCount : 5; - unsigned m_isUsingSingleSlot : 1; - // 4 free bits - }; - - inline size_t Structure::get(const Identifier& propertyName) - { - ASSERT(!propertyName.isNull()); - - materializePropertyMapIfNecessary(); - if (!m_propertyTable) - return WTF::notFound; - - StringImpl* rep = propertyName.impl(); - - unsigned i = rep->existingHash(); - -#if DUMP_PROPERTYMAP_STATS - ++numProbes; -#endif - - unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - return WTF::notFound; - - if (rep == m_propertyTable->entries()[entryIndex - 1].key) - return m_propertyTable->entries()[entryIndex - 1].offset; - -#if DUMP_PROPERTYMAP_STATS - ++numCollisions; -#endif - - unsigned k = 1 | WTF::doubleHash(rep->existingHash()); - - while (1) { - i += k; - -#if DUMP_PROPERTYMAP_STATS - ++numRehashes; -#endif - - entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; - if (entryIndex == emptyEntryIndex) - return WTF::notFound; - - if (rep == m_propertyTable->entries()[entryIndex - 1].key) - return m_propertyTable->entries()[entryIndex - 1].offset; - } - } - -} // namespace JSC - -#endif // Structure_h diff --git a/JavaScriptCore/runtime/StructureChain.cpp b/JavaScriptCore/runtime/StructureChain.cpp deleted file mode 100644 index 085876c..0000000 --- a/JavaScriptCore/runtime/StructureChain.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "StructureChain.h" - -#include "JSObject.h" -#include "Structure.h" -#include <wtf/RefPtr.h> - -namespace JSC { - -StructureChain::StructureChain(Structure* head) -{ - size_t size = 0; - for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure()) - ++size; - - m_vector.set(new RefPtr<Structure>[size + 1]); - - size_t i = 0; - for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure()) - m_vector[i++] = current; - m_vector[i] = 0; -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/StructureChain.h b/JavaScriptCore/runtime/StructureChain.h deleted file mode 100644 index 816b66d..0000000 --- a/JavaScriptCore/runtime/StructureChain.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StructureChain_h -#define StructureChain_h - -#include <wtf/OwnArrayPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> - -namespace JSC { - - class Structure; - - class StructureChain : public RefCounted<StructureChain> { - friend class JIT; - - public: - static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); } - RefPtr<Structure>* head() { return m_vector.get(); } - - private: - StructureChain(Structure* head); - - OwnArrayPtr<RefPtr<Structure> > m_vector; - }; - -} // namespace JSC - -#endif // StructureChain_h diff --git a/JavaScriptCore/runtime/StructureTransitionTable.h b/JavaScriptCore/runtime/StructureTransitionTable.h deleted file mode 100644 index 7e9d7ff..0000000 --- a/JavaScriptCore/runtime/StructureTransitionTable.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StructureTransitionTable_h -#define StructureTransitionTable_h - -#include "UString.h" -#include <wtf/HashFunctions.h> -#include <wtf/HashMap.h> -#include <wtf/HashTraits.h> -#include <wtf/OwnPtr.h> -#include <wtf/RefPtr.h> - -namespace JSC { - - class Structure; - - struct StructureTransitionTableHash { - typedef std::pair<RefPtr<StringImpl>, unsigned> Key; - static unsigned hash(const Key& p) - { - return p.first->existingHash(); - } - - static bool equal(const Key& a, const Key& b) - { - return a == b; - } - - static const bool safeToCompareToEmptyOrDeleted = true; - }; - - struct StructureTransitionTableHashTraits { - typedef WTF::HashTraits<RefPtr<StringImpl> > FirstTraits; - typedef WTF::GenericHashTraits<unsigned> SecondTraits; - typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType > TraitType; - - static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero; - static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); } - - static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction; - - static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); } - static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); } - }; - -} // namespace JSC - -#endif // StructureTransitionTable_h diff --git a/JavaScriptCore/runtime/SymbolTable.h b/JavaScriptCore/runtime/SymbolTable.h deleted file mode 100644 index 1b1636d..0000000 --- a/JavaScriptCore/runtime/SymbolTable.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SymbolTable_h -#define SymbolTable_h - -#include "JSObject.h" -#include "UString.h" -#include <wtf/AlwaysInline.h> - -namespace JSC { - - static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); } - - // The bit twiddling in this class assumes that every register index is a - // reasonably small positive or negative number, and therefore has its high - // four bits all set or all unset. - - struct SymbolTableEntry { - SymbolTableEntry() - : m_bits(0) - { - } - - SymbolTableEntry(int index) - { - ASSERT(isValidIndex(index)); - pack(index, false, false); - } - - SymbolTableEntry(int index, unsigned attributes) - { - ASSERT(isValidIndex(index)); - pack(index, attributes & ReadOnly, attributes & DontEnum); - } - - bool isNull() const - { - return !m_bits; - } - - int getIndex() const - { - return m_bits >> FlagBits; - } - - unsigned getAttributes() const - { - unsigned attributes = 0; - if (m_bits & ReadOnlyFlag) - attributes |= ReadOnly; - if (m_bits & DontEnumFlag) - attributes |= DontEnum; - return attributes; - } - - void setAttributes(unsigned attributes) - { - pack(getIndex(), attributes & ReadOnly, attributes & DontEnum); - } - - bool isReadOnly() const - { - return m_bits & ReadOnlyFlag; - } - - private: - static const unsigned ReadOnlyFlag = 0x1; - static const unsigned DontEnumFlag = 0x2; - static const unsigned NotNullFlag = 0x4; - static const unsigned FlagBits = 3; - - void pack(int index, bool readOnly, bool dontEnum) - { - m_bits = (index << FlagBits) | NotNullFlag; - if (readOnly) - m_bits |= ReadOnlyFlag; - if (dontEnum) - m_bits |= DontEnumFlag; - } - - bool isValidIndex(int index) - { - return ((index << FlagBits) >> FlagBits) == index; - } - - int m_bits; - }; - - struct SymbolTableIndexHashTraits { - typedef SymbolTableEntry TraitType; - static SymbolTableEntry emptyValue() { return SymbolTableEntry(); } - static const bool emptyValueIsZero = true; - static const bool needsDestruction = false; - }; - - typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable; - - class SharedSymbolTable : public SymbolTable, public RefCounted<SharedSymbolTable> { - public: - static PassRefPtr<SharedSymbolTable> create() { return adoptRef(new SharedSymbolTable); } - private: - SharedSymbolTable() { } - }; - -} // namespace JSC - -#endif // SymbolTable_h diff --git a/JavaScriptCore/runtime/Terminator.h b/JavaScriptCore/runtime/Terminator.h deleted file mode 100644 index 6b0f236..0000000 --- a/JavaScriptCore/runtime/Terminator.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010 Google 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 Google Inc. ("Google") 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 Terminator_h -#define Terminator_h - -namespace JSC { - -class Terminator { -public: - Terminator() : m_shouldTerminate(false) { } - - void terminateSoon() { m_shouldTerminate = true; } - bool shouldTerminate() const { return m_shouldTerminate; } - -private: - bool m_shouldTerminate; -}; - -} // namespace JSC - -#endif // Terminator_h diff --git a/JavaScriptCore/runtime/TimeoutChecker.cpp b/JavaScriptCore/runtime/TimeoutChecker.cpp deleted file mode 100644 index 04d904d..0000000 --- a/JavaScriptCore/runtime/TimeoutChecker.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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 OS(DARWIN) -#include <mach/mach.h> -#elif OS(WINDOWS) -#include <windows.h> -#else -#include "CurrentTime.h" -#endif - -#if PLATFORM(BREWMP) -#include <AEEStdLib.h> -#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 OS(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 OS(WINDOWS) - 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; -#elif OS(SYMBIAN) - RThread current; - TTimeIntervalMicroSeconds cpuTime; - - TInt err = current.GetCpuTime(cpuTime); - ASSERT_WITH_MESSAGE(err == KErrNone, "GetCpuTime failed with %d", err); - return cpuTime.Int64() / 1000; -#elif PLATFORM(BREWMP) - // This function returns a continuously and linearly increasing millisecond - // timer from the time the device was powered on. - // There is only one thread in BREW, so this is enough. - return GETUPTIMEMS(); -#else - // FIXME: We should return the time the current thread has spent executing. - - // use a relative time from first call in order to avoid an overflow - static double firstTime = currentTime(); - return (currentTime() - firstTime) * 1000; -#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/JavaScriptCore/runtime/TimeoutChecker.h b/JavaScriptCore/runtime/TimeoutChecker.h deleted file mode 100644 index 71ce169..0000000 --- a/JavaScriptCore/runtime/TimeoutChecker.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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> - -#ifdef ANDROID_INSTRUMENT -#include "TimeCounter.h" -#endif - -namespace JSC { - - class ExecState; - - class TimeoutChecker { - public: - TimeoutChecker(); - - void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; } - unsigned timeoutInterval() const { return m_timeoutInterval; } - - unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; } - - void start() - { - if (!m_startCount) - reset(); -#ifdef ANDROID_INSTRUMENT - if (!m_startCount) - android::TimeCounter::start(android::TimeCounter::JavaScriptTimeCounter); -#endif - ++m_startCount; - } - - void stop() - { - ASSERT(m_startCount); - --m_startCount; -#ifdef ANDROID_INSTRUMENT - if (!m_startCount) - android::TimeCounter::record(android::TimeCounter::JavaScriptTimeCounter, __FUNCTION__); -#endif - } - - 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/JavaScriptCore/runtime/Tracing.d b/JavaScriptCore/runtime/Tracing.d deleted file mode 100644 index da854b9..0000000 --- a/JavaScriptCore/runtime/Tracing.d +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -provider JavaScriptCore -{ - probe gc__begin(); - probe gc__marked(); - probe gc__end(); - - probe profile__will_execute(int, char*, char*, int); - probe profile__did_execute(int, char*, char*, int); -}; - -#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore provider -#pragma D attributes Private/Private/Unknown provider JavaScriptCore module -#pragma D attributes Private/Private/Unknown provider JavaScriptCore function -#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore name -#pragma D attributes Unstable/Unstable/Common provider JavaScriptCore args diff --git a/JavaScriptCore/runtime/Tracing.h b/JavaScriptCore/runtime/Tracing.h deleted file mode 100644 index c28c85f..0000000 --- a/JavaScriptCore/runtime/Tracing.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef Tracing_h -#define Tracing_h - -#if HAVE(DTRACE) -#include "TracingDtrace.h" -#else - -#define JAVASCRIPTCORE_GC_BEGIN() -#define JAVASCRIPTCORE_GC_BEGIN_ENABLED() 0 - -#define JAVASCRIPTCORE_GC_END() -#define JAVASCRIPTCORE_GC_END_ENABLED() 0 - -#define JAVASCRIPTCORE_GC_MARKED() -#define JAVASCRIPTCORE_GC_MARKED_ENABLED() 0 - -#define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(arg0, arg1, arg2, arg3) -#define JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED() 0 - -#define JAVASCRIPTCORE_PROFILE_DID_EXECUTE(arg0, arg1, arg2, arg3) -#define JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED() 0 - -#endif - -#endif // Tracing_h diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp deleted file mode 100644 index b3cd40c..0000000 --- a/JavaScriptCore/runtime/UString.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "UString.h" - -#include "JSGlobalObjectFunctions.h" -#include "Collector.h" -#include "Identifier.h" -#include "Operations.h" -#include <ctype.h> -#include <limits.h> -#include <limits> -#include <stdio.h> -#include <stdlib.h> -#include <wtf/ASCIICType.h> -#include <wtf/Assertions.h> -#include <wtf/DecimalNumber.h> -#include <wtf/MathExtras.h> -#include <wtf/StringExtras.h> -#include <wtf/Vector.h> -#include <wtf/unicode/UTF8.h> - -#if HAVE(STRINGS_H) -#include <strings.h> -#endif - -using namespace WTF; -using namespace WTF::Unicode; -using namespace std; - -namespace JSC { - -extern const double NaN; -extern const double Inf; - -COMPILE_ASSERT(sizeof(UString) == sizeof(void*), UString_should_stay_small); - -// Construct a string with UTF-16 data. -UString::UString(const UChar* characters, unsigned length) - : m_impl(characters ? StringImpl::create(characters, length) : 0) -{ -} - -// Construct a string with UTF-16 data, from a null-terminated source. -UString::UString(const UChar* characters) -{ - if (!characters) - return; - - int length = 0; - while (characters[length] != UChar(0)) - ++length; - - m_impl = StringImpl::create(characters, length); -} - -// Construct a string with latin1 data. -UString::UString(const char* characters, unsigned length) - : m_impl(characters ? StringImpl::create(characters, length) : 0) -{ -} - -// Construct a string with latin1 data, from a null-terminated source. -UString::UString(const char* characters) - : m_impl(characters ? StringImpl::create(characters) : 0) -{ -} - -UString UString::number(int i) -{ - UChar buf[1 + sizeof(i) * 3]; - UChar* end = buf + WTF_ARRAY_LENGTH(buf); - UChar* p = end; - - if (i == 0) - *--p = '0'; - else if (i == INT_MIN) { - char minBuf[1 + sizeof(i) * 3]; - snprintf(minBuf, sizeof(minBuf), "%d", INT_MIN); - return UString(minBuf); - } else { - bool negative = false; - if (i < 0) { - negative = true; - i = -i; - } - while (i) { - *--p = static_cast<unsigned short>((i % 10) + '0'); - i /= 10; - } - if (negative) - *--p = '-'; - } - - return UString(p, static_cast<unsigned>(end - p)); -} - -UString UString::number(long long i) -{ - UChar buf[1 + sizeof(i) * 3]; - UChar* end = buf + WTF_ARRAY_LENGTH(buf); - UChar* p = end; - - if (i == 0) - *--p = '0'; - else if (i == std::numeric_limits<long long>::min()) { - char minBuf[1 + sizeof(i) * 3]; -#if OS(WINDOWS) - snprintf(minBuf, sizeof(minBuf), "%I64d", std::numeric_limits<long long>::min()); -#else - snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min()); -#endif - return UString(minBuf); - } else { - bool negative = false; - if (i < 0) { - negative = true; - i = -i; - } - while (i) { - *--p = static_cast<unsigned short>((i % 10) + '0'); - i /= 10; - } - if (negative) - *--p = '-'; - } - - return UString(p, static_cast<unsigned>(end - p)); -} - -UString UString::number(unsigned u) -{ - UChar buf[sizeof(u) * 3]; - UChar* end = buf + WTF_ARRAY_LENGTH(buf); - UChar* p = end; - - if (u == 0) - *--p = '0'; - else { - while (u) { - *--p = static_cast<unsigned short>((u % 10) + '0'); - u /= 10; - } - } - - return UString(p, static_cast<unsigned>(end - p)); -} - -UString UString::number(long l) -{ - UChar buf[1 + sizeof(l) * 3]; - UChar* end = buf + WTF_ARRAY_LENGTH(buf); - UChar* p = end; - - if (l == 0) - *--p = '0'; - else if (l == LONG_MIN) { - char minBuf[1 + sizeof(l) * 3]; - snprintf(minBuf, sizeof(minBuf), "%ld", LONG_MIN); - return UString(minBuf); - } else { - bool negative = false; - if (l < 0) { - negative = true; - l = -l; - } - while (l) { - *--p = static_cast<unsigned short>((l % 10) + '0'); - l /= 10; - } - if (negative) - *--p = '-'; - } - - return UString(p, end - p); -} - -UString UString::number(double d) -{ - NumberToStringBuffer buffer; - unsigned length = numberToString(d, buffer); - return UString(buffer, length); -} - -UString UString::substringSharingImpl(unsigned offset, unsigned length) const -{ - // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar). - - unsigned stringLength = this->length(); - offset = min(offset, stringLength); - length = min(length, stringLength - offset); - - if (!offset && length == stringLength) - return *this; - return UString(StringImpl::create(m_impl, offset, length)); -} - -bool operator==(const UString& s1, const char *s2) -{ - if (s2 == 0) - return s1.isEmpty(); - - const UChar* u = s1.characters(); - const UChar* uend = u + s1.length(); - while (u != uend && *s2) { - if (u[0] != (unsigned char)*s2) - return false; - s2++; - u++; - } - - return u == uend && *s2 == 0; -} - -bool operator<(const UString& s1, const UString& s2) -{ - const unsigned l1 = s1.length(); - const unsigned l2 = s2.length(); - const unsigned lmin = l1 < l2 ? l1 : l2; - const UChar* c1 = s1.characters(); - const UChar* c2 = s2.characters(); - unsigned l = 0; - while (l < lmin && *c1 == *c2) { - c1++; - c2++; - l++; - } - if (l < lmin) - return (c1[0] < c2[0]); - - return (l1 < l2); -} - -bool operator>(const UString& s1, const UString& s2) -{ - const unsigned l1 = s1.length(); - const unsigned l2 = s2.length(); - const unsigned lmin = l1 < l2 ? l1 : l2; - const UChar* c1 = s1.characters(); - const UChar* c2 = s2.characters(); - unsigned l = 0; - while (l < lmin && *c1 == *c2) { - c1++; - c2++; - l++; - } - if (l < lmin) - return (c1[0] > c2[0]); - - return (l1 > l2); -} - -CString UString::ascii() const -{ - // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are - // preserved, characters outside of this range are converted to '?'. - - unsigned length = this->length(); - const UChar* characters = this->characters(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - characterBuffer[i] = ch && (ch < 0x20 || ch >= 0x7f) ? '?' : ch; - } - - return result; -} - -CString UString::latin1() const -{ - // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are - // preserved, characters outside of this range are converted to '?'. - - unsigned length = this->length(); - const UChar* characters = this->characters(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - characterBuffer[i] = ch > 0xff ? '?' : ch; - } - - return result; -} - -// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. -static inline void putUTF8Triple(char*& buffer, UChar ch) -{ - ASSERT(ch >= 0x0800); - *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); - *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); - *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); -} - -CString UString::utf8(bool strict) const -{ - unsigned length = this->length(); - const UChar* characters = this->characters(); - - // Allocate a buffer big enough to hold all the characters - // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). - // Optimization ideas, if we find this function is hot: - // * We could speculatively create a CStringBuffer to contain 'length' - // characters, and resize if necessary (i.e. if the buffer contains - // non-ascii characters). (Alternatively, scan the buffer first for - // ascii characters, so we know this will be sufficient). - // * We could allocate a CStringBuffer with an appropriate size to - // have a good chance of being able to write the string into the - // buffer without reallocing (say, 1.5 x length). - if (length > numeric_limits<unsigned>::max() / 3) - return CString(); - Vector<char, 1024> bufferVector(length * 3); - - char* buffer = bufferVector.data(); - ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); - ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion - - // Only produced from strict conversion. - if (result == sourceIllegal) - return CString(); - - // Check for an unconverted high surrogate. - if (result == sourceExhausted) { - if (strict) - return CString(); - // This should be one unpaired high surrogate. Treat it the same - // was as an unpaired high surrogate would have been handled in - // the middle of a string with non-strict conversion - which is - // to say, simply encode it to UTF-8. - ASSERT((characters + 1) == (this->characters() + length)); - ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); - // There should be room left, since one UChar hasn't been converted. - ASSERT((buffer + 3) <= (buffer + bufferVector.size())); - putUTF8Triple(buffer, *characters); - } - - return CString(bufferVector.data(), buffer - bufferVector.data()); -} - -} // namespace JSC diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h deleted file mode 100644 index 8f6c083..0000000 --- a/JavaScriptCore/runtime/UString.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef UString_h -#define UString_h - -#include <wtf/text/StringImpl.h> - -namespace JSC { - -class UString { -public: - // Construct a null string, distinguishable from an empty string. - UString() { } - - // Construct a string with UTF-16 data. - UString(const UChar* characters, unsigned length); - - // Construct a string with UTF-16 data, from a null-terminated source. - UString(const UChar*); - - // Construct a string with latin1 data. - UString(const char* characters, unsigned length); - - // Construct a string with latin1 data, from a null-terminated source. - UString(const char* characters); - - // Construct a string referencing an existing StringImpl. - UString(StringImpl* impl) : m_impl(impl) { } - UString(PassRefPtr<StringImpl> impl) : m_impl(impl) { } - UString(RefPtr<StringImpl> impl) : m_impl(impl) { } - - // Inline the destructor. - ALWAYS_INLINE ~UString() { } - - void swap(UString& o) { m_impl.swap(o.m_impl); } - - template<size_t inlineCapacity> - static UString adopt(Vector<UChar, inlineCapacity>& vector) { return StringImpl::adopt(vector); } - - bool isNull() const { return !m_impl; } - bool isEmpty() const { return !m_impl || !m_impl->length(); } - - StringImpl* impl() const { return m_impl.get(); } - - unsigned length() const - { - if (!m_impl) - return 0; - return m_impl->length(); - } - - const UChar* characters() const - { - if (!m_impl) - return 0; - return m_impl->characters(); - } - - CString ascii() const; - CString latin1() const; - CString utf8(bool strict = false) const; - - UChar operator[](unsigned index) const - { - if (!m_impl || index >= m_impl->length()) - return 0; - return m_impl->characters()[index]; - } - - static UString number(int); - static UString number(unsigned); - static UString number(long); - static UString number(long long); - static UString number(double); - - // Find a single character or string, also with match function & latin1 forms. - size_t find(UChar c, unsigned start = 0) const - { return m_impl ? m_impl->find(c, start) : notFound; } - size_t find(const UString& str, unsigned start = 0) const - { return m_impl ? m_impl->find(str.impl(), start) : notFound; } - size_t find(const char* str, unsigned start = 0) const - { return m_impl ? m_impl->find(str, start) : notFound; } - - // Find the last instance of a single character or string. - size_t reverseFind(UChar c, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFind(c, start) : notFound; } - size_t reverseFind(const UString& str, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; } - - UString substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const; - -private: - RefPtr<StringImpl> m_impl; -}; - -ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) -{ - StringImpl* rep1 = s1.impl(); - StringImpl* rep2 = s2.impl(); - unsigned size1 = 0; - unsigned size2 = 0; - - if (rep1 == rep2) // If they're the same rep, they're equal. - return true; - - if (rep1) - size1 = rep1->length(); - - if (rep2) - size2 = rep2->length(); - - if (size1 != size2) // If the lengths are not the same, we're done. - return false; - - if (!size1) - return true; - - // At this point we know - // (a) that the strings are the same length and - // (b) that they are greater than zero length. - const UChar* d1 = rep1->characters(); - const UChar* d2 = rep2->characters(); - - if (d1 == d2) // Check to see if the data pointers are the same. - return true; - - // Do quick checks for sizes 1 and 2. - switch (size1) { - case 1: - return d1[0] == d2[0]; - case 2: - return (d1[0] == d2[0]) & (d1[1] == d2[1]); - default: - return memcmp(d1, d2, size1 * sizeof(UChar)) == 0; - } -} - - -inline bool operator!=(const UString& s1, const UString& s2) -{ - return !JSC::operator==(s1, s2); -} - -bool operator<(const UString& s1, const UString& s2); -bool operator>(const UString& s1, const UString& s2); - -bool operator==(const UString& s1, const char* s2); - -inline bool operator!=(const UString& s1, const char* s2) -{ - return !JSC::operator==(s1, s2); -} - -inline bool operator==(const char *s1, const UString& s2) -{ - return operator==(s2, s1); -} - -inline bool operator!=(const char *s1, const UString& s2) -{ - return !JSC::operator==(s1, s2); -} - -inline int codePointCompare(const UString& s1, const UString& s2) -{ - return codePointCompare(s1.impl(), s2.impl()); -} - -struct UStringHash { - static unsigned hash(StringImpl* key) { return key->hash(); } - static bool equal(const StringImpl* a, const StringImpl* b) - { - if (a == b) - return true; - if (!a || !b) - return false; - - unsigned aLength = a->length(); - unsigned bLength = b->length(); - if (aLength != bLength) - return false; - - // FIXME: perhaps we should have a more abstract macro that indicates when - // going 4 bytes at a time is unsafe -#if CPU(ARM) || CPU(SH4) || CPU(MIPS) - const UChar* aChars = a->characters(); - const UChar* bChars = b->characters(); - for (unsigned i = 0; i != aLength; ++i) { - if (*aChars++ != *bChars++) - return false; - } - return true; -#else - /* Do it 4-bytes-at-a-time on architectures where it's safe */ - const uint32_t* aChars = reinterpret_cast<const uint32_t*>(a->characters()); - const uint32_t* bChars = reinterpret_cast<const uint32_t*>(b->characters()); - - unsigned halfLength = aLength >> 1; - for (unsigned i = 0; i != halfLength; ++i) - if (*aChars++ != *bChars++) - return false; - - if (aLength & 1 && *reinterpret_cast<const uint16_t*>(aChars) != *reinterpret_cast<const uint16_t*>(bChars)) - return false; - - return true; -#endif - } - - static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); } - static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b) - { - return equal(a.get(), b.get()); - } - - static unsigned hash(const UString& key) { return key.impl()->hash(); } - static bool equal(const UString& a, const UString& b) - { - return equal(a.impl(), b.impl()); - } - - static const bool safeToCompareToEmptyOrDeleted = false; -}; - -} // namespace JSC - -namespace WTF { - -// UStringHash is the default hash for UString -template<typename T> struct DefaultHash; -template<> struct DefaultHash<JSC::UString> { - typedef JSC::UStringHash Hash; -}; - -template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits -{ - static const bool canInitializeWithMemset = true; -}; - -} // namespace WTF - -#endif - diff --git a/JavaScriptCore/runtime/UStringBuilder.h b/JavaScriptCore/runtime/UStringBuilder.h deleted file mode 100644 index 31ccf38..0000000 --- a/JavaScriptCore/runtime/UStringBuilder.h +++ /dev/null @@ -1,43 +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 UStringBuilder_h -#define UStringBuilder_h - -#include <wtf/text/StringBuilder.h> - -namespace JSC { - -class UStringBuilder : public StringBuilder { -public: - using StringBuilder::append; - void append(const UString& str) { append(String(str.impl())); } - - UString toUString() { return toString().impl(); } -}; - -} // namespace JSC - -#endif // UStringBuilder_h diff --git a/JavaScriptCore/runtime/UStringConcatenate.h b/JavaScriptCore/runtime/UStringConcatenate.h deleted file mode 100644 index 0990c72..0000000 --- a/JavaScriptCore/runtime/UStringConcatenate.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2010 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 UStringConcatenate_h -#define UStringConcatenate_h - -#include "UString.h" -#include <wtf/text/StringConcatenate.h> - -namespace WTF { - -template<> -class StringTypeAdapter<JSC::UString> { -public: - StringTypeAdapter<JSC::UString>(JSC::UString& string) - : m_data(string.characters()) - , m_length(string.length()) - { - } - - unsigned length() { return m_length; } - - void writeTo(UChar* destination) - { - for (unsigned i = 0; i < m_length; ++i) - destination[i] = m_data[i]; - } - -private: - const UChar* m_data; - unsigned m_length; -}; - -}; // namespace WTF - -namespace JSC { - -template<typename StringType1, typename StringType2> -UString makeUString(StringType1 string1, StringType2 string2) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6, string7); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -} // namespace JSC - -#endif diff --git a/JavaScriptCore/runtime/WeakGCMap.h b/JavaScriptCore/runtime/WeakGCMap.h deleted file mode 100644 index 39a91c5..0000000 --- a/JavaScriptCore/runtime/WeakGCMap.h +++ /dev/null @@ -1,122 +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. 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 INC. 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 WeakGCMap_h -#define WeakGCMap_h - -#include "Collector.h" -#include <wtf/HashMap.h> - -namespace JSC { - -class JSCell; - -// A HashMap whose get() function returns emptyValue() for cells awaiting destruction. -template<typename KeyType, typename MappedType> -class WeakGCMap : public FastAllocBase { - /* - Invariants: - * A value enters the WeakGCMap marked. (Guaranteed by set().) - * A value that becomes unmarked leaves the WeakGCMap before being recycled. (Guaranteed by the value's destructor removing it from the WeakGCMap.) - * A value that becomes unmarked leaves the WeakGCMap before becoming marked again. (Guaranteed by all destructors running before the mark phase begins.) - * During the mark phase, all values in the WeakGCMap are valid. (Guaranteed by all destructors running before the mark phase begins.) - */ - -public: - typedef typename HashMap<KeyType, MappedType>::iterator iterator; - typedef typename HashMap<KeyType, MappedType>::const_iterator const_iterator; - - bool isEmpty() { return m_map.isEmpty(); } - - MappedType get(const KeyType& key) const; - pair<iterator, bool> set(const KeyType&, const MappedType&); - MappedType take(const KeyType& key); - - // These unchecked functions provide access to a value even if the value's - // mark bit is not set. This is used, among other things, to retrieve values - // during the GC mark phase, which begins by clearing all mark bits. - - MappedType uncheckedGet(const KeyType& key) const { return m_map.get(key); } - bool uncheckedRemove(const KeyType&, const MappedType&); - - iterator uncheckedBegin() { return m_map.begin(); } - iterator uncheckedEnd() { return m_map.end(); } - - const_iterator uncheckedBegin() const { return m_map.begin(); } - const_iterator uncheckedEnd() const { return m_map.end(); } - -private: - HashMap<KeyType, MappedType> m_map; -}; - -template<typename KeyType, typename MappedType> -inline MappedType WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const -{ - MappedType result = m_map.get(key); - if (result == HashTraits<MappedType>::emptyValue()) - return result; - if (!Heap::isCellMarked(result)) - return HashTraits<MappedType>::emptyValue(); - return result; -} - -template<typename KeyType, typename MappedType> -MappedType WeakGCMap<KeyType, MappedType>::take(const KeyType& key) -{ - MappedType result = m_map.take(key); - if (result == HashTraits<MappedType>::emptyValue()) - return result; - if (!Heap::isCellMarked(result)) - return HashTraits<MappedType>::emptyValue(); - return result; -} - -template<typename KeyType, typename MappedType> -pair<typename HashMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, const MappedType& value) -{ - Heap::markCell(value); // If value is newly allocated, it's not marked, so mark it now. - pair<iterator, bool> result = m_map.add(key, value); - if (!result.second) { // pre-existing entry - result.second = !Heap::isCellMarked(result.first->second); - result.first->second = value; - } - return result; -} - -template<typename KeyType, typename MappedType> -bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, const MappedType& value) -{ - iterator it = m_map.find(key); - if (it == m_map.end()) - return false; - if (it->second != value) - return false; - m_map.remove(it); - return true; -} - -} // namespace JSC - -#endif // WeakGCMap_h diff --git a/JavaScriptCore/runtime/WeakGCPtr.h b/JavaScriptCore/runtime/WeakGCPtr.h deleted file mode 100644 index ac77cf3..0000000 --- a/JavaScriptCore/runtime/WeakGCPtr.h +++ /dev/null @@ -1,153 +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. 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 INC. 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 WeakGCPtr_h -#define WeakGCPtr_h - -#include "Collector.h" -#include "GCHandle.h" -#include <wtf/Noncopyable.h> - -namespace JSC { - -// A smart pointer whose get() function returns 0 for cells awaiting destruction. -template <typename T> class WeakGCPtr : Noncopyable { -public: - WeakGCPtr() - : m_ptr(0) - { - } - - WeakGCPtr(T* ptr) { assign(ptr); } - - ~WeakGCPtr() - { - if (m_ptr) - m_ptr->pool()->free(m_ptr); - } - - T* get() const - { - if (m_ptr && m_ptr->isValidPtr()) - return static_cast<T*>(m_ptr->get()); - return 0; - } - - bool clear(JSCell* p) - { - if (!m_ptr || m_ptr->get() != p) - return false; - - m_ptr->pool()->free(m_ptr); - m_ptr = 0; - return true; - } - - T& operator*() const { return *get(); } - T* operator->() const { return get(); } - - bool operator!() const { return !get(); } - - // This conversion operator allows implicit conversion to bool but not to other integer types. -#if COMPILER(WINSCW) - operator bool() const { return m_ptr; } -#else - typedef WeakGCHandle* WeakGCPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return get() ? &WeakGCPtr::m_ptr : 0; } -#endif - - WeakGCPtr& operator=(T*); - -#if !ASSERT_DISABLED - bool hasDeadObject() const { return !!m_ptr; } -#endif - -private: - void assign(JSCell* ptr) - { - ASSERT(ptr); - if (m_ptr) - m_ptr->set(ptr); - else - m_ptr = Heap::heap(ptr)->addWeakGCHandle(ptr); - } - - WeakGCHandle* m_ptr; -}; - -template <typename T> inline WeakGCPtr<T>& WeakGCPtr<T>::operator=(T* optr) -{ - assign(optr); - return *this; -} - -template <typename T, typename U> inline bool operator==(const WeakGCPtr<T>& a, const WeakGCPtr<U>& b) -{ - return a.get() == b.get(); -} - -template <typename T, typename U> inline bool operator==(const WeakGCPtr<T>& a, U* b) -{ - return a.get() == b; -} - -template <typename T, typename U> inline bool operator==(T* a, const WeakGCPtr<U>& b) -{ - return a == b.get(); -} - -template <typename T, typename U> inline bool operator!=(const WeakGCPtr<T>& a, const WeakGCPtr<U>& b) -{ - return a.get() != b.get(); -} - -template <typename T, typename U> inline bool operator!=(const WeakGCPtr<T>& a, U* b) -{ - return a.get() != b; -} - -template <typename T, typename U> inline bool operator!=(T* a, const WeakGCPtr<U>& b) -{ - return a != b.get(); -} - -template <typename T, typename U> inline WeakGCPtr<T> static_pointer_cast(const WeakGCPtr<U>& p) -{ - return WeakGCPtr<T>(static_cast<T*>(p.get())); -} - -template <typename T, typename U> inline WeakGCPtr<T> const_pointer_cast(const WeakGCPtr<U>& p) -{ - return WeakGCPtr<T>(const_cast<T*>(p.get())); -} - -template <typename T> inline T* get(const WeakGCPtr<T>& p) -{ - return p.get(); -} - -} // namespace JSC - -#endif // WeakGCPtr_h diff --git a/JavaScriptCore/runtime/WeakRandom.h b/JavaScriptCore/runtime/WeakRandom.h deleted file mode 100644 index ff3995e..0000000 --- a/JavaScriptCore/runtime/WeakRandom.h +++ /dev/null @@ -1,86 +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. - * - * - * Copyright (c) 2009 Ian C. Bullard - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef WeakRandom_h -#define WeakRandom_h - -#include <limits.h> -#include <wtf/StdLibExtras.h> - -namespace JSC { - -class WeakRandom { -public: - WeakRandom(unsigned seed) - : m_low(seed ^ 0x49616E42) - , m_high(seed) - { - } - - double get() - { - return advance() / (UINT_MAX + 1.0); - } - -private: - unsigned advance() - { - m_high = (m_high << 16) + (m_high >> 16); - m_high += m_low; - m_low += m_high; - return m_high; - } - - unsigned m_low; - unsigned m_high; -}; - -} // namespace JSC - -#endif // WeakRandom_h |