ArgList.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. #ifndef ArgList_h
  22. #define ArgList_h
  23. #include "CallFrame.h"
  24. #include "Register.h"
  25. #include <wtf/HashSet.h>
  26. #include <wtf/Vector.h>
  27. namespace JSC {
  28. class SlotVisitor;
  29. class MarkedArgumentBuffer {
  30. WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
  31. friend class VM;
  32. friend class ArgList;
  33. private:
  34. static const size_t inlineCapacity = 8;
  35. typedef HashSet<MarkedArgumentBuffer*> ListSet;
  36. public:
  37. // Constructor for a read-write list, to which you may append values.
  38. // FIXME: Remove all clients of this API, then remove this API.
  39. MarkedArgumentBuffer()
  40. : m_size(0)
  41. , m_capacity(inlineCapacity)
  42. , m_buffer(&m_inlineBuffer[m_capacity - 1])
  43. , m_markSet(0)
  44. {
  45. }
  46. ~MarkedArgumentBuffer()
  47. {
  48. if (m_markSet)
  49. m_markSet->remove(this);
  50. if (EncodedJSValue* base = mallocBase())
  51. delete [] base;
  52. }
  53. size_t size() const { return m_size; }
  54. bool isEmpty() const { return !m_size; }
  55. JSValue at(int i) const
  56. {
  57. if (i >= m_size)
  58. return jsUndefined();
  59. return JSValue::decode(slotFor(i));
  60. }
  61. void clear()
  62. {
  63. m_size = 0;
  64. }
  65. void append(JSValue v)
  66. {
  67. if (m_size >= m_capacity)
  68. return slowAppend(v);
  69. slotFor(m_size) = JSValue::encode(v);
  70. ++m_size;
  71. }
  72. void removeLast()
  73. {
  74. ASSERT(m_size);
  75. m_size--;
  76. }
  77. JSValue last()
  78. {
  79. ASSERT(m_size);
  80. return JSValue::decode(slotFor(m_size - 1));
  81. }
  82. static void markLists(HeapRootVisitor&, ListSet&);
  83. private:
  84. JS_EXPORT_PRIVATE void slowAppend(JSValue);
  85. EncodedJSValue& slotFor(int item) const
  86. {
  87. return m_buffer[-item];
  88. }
  89. EncodedJSValue* mallocBase()
  90. {
  91. if (m_capacity == static_cast<int>(inlineCapacity))
  92. return 0;
  93. return &slotFor(m_capacity - 1);
  94. }
  95. int m_size;
  96. int m_capacity;
  97. EncodedJSValue m_inlineBuffer[inlineCapacity];
  98. EncodedJSValue* m_buffer;
  99. ListSet* m_markSet;
  100. private:
  101. // Prohibits new / delete, which would break GC.
  102. void* operator new(size_t size)
  103. {
  104. return fastMalloc(size);
  105. }
  106. void operator delete(void* p)
  107. {
  108. fastFree(p);
  109. }
  110. void* operator new[](size_t);
  111. void operator delete[](void*);
  112. void* operator new(size_t, void*);
  113. void operator delete(void*, size_t);
  114. };
  115. class ArgList {
  116. friend class JIT;
  117. public:
  118. ArgList()
  119. : m_args(0)
  120. , m_argCount(0)
  121. {
  122. }
  123. ArgList(ExecState* exec)
  124. : m_args(reinterpret_cast<JSValue*>(&exec[CallFrame::argumentOffset(0)]))
  125. , m_argCount(exec->argumentCount())
  126. {
  127. }
  128. ArgList(const MarkedArgumentBuffer& args)
  129. : m_args(reinterpret_cast<JSValue*>(args.m_buffer))
  130. , m_argCount(args.size())
  131. {
  132. }
  133. JSValue at(int i) const
  134. {
  135. if (i >= m_argCount)
  136. return jsUndefined();
  137. return m_args[-i];
  138. }
  139. bool isEmpty() const { return !m_argCount; }
  140. size_t size() const { return m_argCount; }
  141. JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const;
  142. private:
  143. JSValue* m_args;
  144. int m_argCount;
  145. };
  146. } // namespace JSC
  147. #endif // ArgList_h