1/* 2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22#ifndef ArgList_h 23#define ArgList_h 24 25#include "CallFrame.h" 26#include "Register.h" 27#include <wtf/HashSet.h> 28#include <wtf/Vector.h> 29 30namespace JSC { 31 32class SlotVisitor; 33 34class MarkedArgumentBuffer { 35 WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer); 36 friend class VM; 37 friend class ArgList; 38 39private: 40 static const size_t inlineCapacity = 8; 41 typedef HashSet<MarkedArgumentBuffer*> ListSet; 42 43public: 44 // Constructor for a read-write list, to which you may append values. 45 // FIXME: Remove all clients of this API, then remove this API. 46 MarkedArgumentBuffer() 47 : m_size(0) 48 , m_capacity(inlineCapacity) 49 , m_buffer(m_inlineBuffer) 50 , m_markSet(0) 51 { 52 } 53 54 ~MarkedArgumentBuffer() 55 { 56 if (m_markSet) 57 m_markSet->remove(this); 58 59 if (EncodedJSValue* base = mallocBase()) 60 delete [] base; 61 } 62 63 size_t size() const { return m_size; } 64 bool isEmpty() const { return !m_size; } 65 66 JSValue at(int i) const 67 { 68 if (i >= m_size) 69 return jsUndefined(); 70 71 return JSValue::decode(slotFor(i)); 72 } 73 74 void clear() 75 { 76 m_size = 0; 77 } 78 79 void append(JSValue v) 80 { 81 if (m_size >= m_capacity) 82 return slowAppend(v); 83 84 slotFor(m_size) = JSValue::encode(v); 85 ++m_size; 86 } 87 88 void removeLast() 89 { 90 ASSERT(m_size); 91 m_size--; 92 } 93 94 JSValue last() 95 { 96 ASSERT(m_size); 97 return JSValue::decode(slotFor(m_size - 1)); 98 } 99 100 static void markLists(HeapRootVisitor&, ListSet&); 101 102private: 103 JS_EXPORT_PRIVATE void slowAppend(JSValue); 104 105 EncodedJSValue& slotFor(int item) const 106 { 107 return m_buffer[item]; 108 } 109 110 EncodedJSValue* mallocBase() 111 { 112 if (m_capacity == static_cast<int>(inlineCapacity)) 113 return 0; 114 return &slotFor(0); 115 } 116 117 int m_size; 118 int m_capacity; 119 EncodedJSValue m_inlineBuffer[inlineCapacity]; 120 EncodedJSValue* m_buffer; 121 ListSet* m_markSet; 122 123private: 124 // Prohibits new / delete, which would break GC. 125 void* operator new(size_t size) 126 { 127 return fastMalloc(size); 128 } 129 void operator delete(void* p) 130 { 131 fastFree(p); 132 } 133 134 void* operator new[](size_t); 135 void operator delete[](void*); 136 137 void* operator new(size_t, void*); 138 void operator delete(void*, size_t); 139}; 140 141class ArgList { 142 friend class Interpreter; 143 friend class JIT; 144public: 145 ArgList() 146 : m_args(0) 147 , m_argCount(0) 148 { 149 } 150 151 ArgList(ExecState* exec) 152 : m_args(reinterpret_cast<JSValue*>(&exec[CallFrame::argumentOffset(0)])) 153 , m_argCount(exec->argumentCount()) 154 { 155 } 156 157 ArgList(const MarkedArgumentBuffer& args) 158 : m_args(reinterpret_cast<JSValue*>(args.m_buffer)) 159 , m_argCount(args.size()) 160 { 161 } 162 163 JSValue at(int i) const 164 { 165 if (i >= m_argCount) 166 return jsUndefined(); 167 return m_args[i]; 168 } 169 170 bool isEmpty() const { return !m_argCount; } 171 size_t size() const { return m_argCount; } 172 173 JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const; 174 175private: 176 JSValue* data() const { return m_args; } 177 178 JSValue* m_args; 179 int m_argCount; 180}; 181 182} // namespace JSC 183 184#endif // ArgList_h 185