]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/ArgList.h
JavaScriptCore-584.tar.gz
[apple/javascriptcore.git] / runtime / ArgList.h
index a1763e0a6e63da66ecdcf4c639330742b5f76133..8e1fdbe4b89af9084b631ae851c3304c1c45ad6c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007, 2008 Apple Computer, Inc.
+ *  Copyright (C) 2003, 2007, 2008, 2009 Apple 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
 #ifndef ArgList_h
 #define ArgList_h
 
-#include "JSImmediate.h"
 #include "Register.h"
-
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
-    
-    class ArgList : Noncopyable {
+
+    class MarkStack;
+
+    class MarkedArgumentBuffer : public Noncopyable {
     private:
         static const unsigned inlineCapacity = 8;
         typedef Vector<Register, inlineCapacity> VectorType;
-        typedef HashSet<ArgList*> ListSet;
+        typedef HashSet<MarkedArgumentBuffer*> ListSet;
 
     public:
         typedef VectorType::iterator iterator;
@@ -43,8 +43,9 @@ namespace JSC {
 
         // Constructor for a read-write list, to which you may append values.
         // FIXME: Remove all clients of this API, then remove this API.
-        ArgList()
-            : m_markSet(0)
+        MarkedArgumentBuffer()
+            : m_isUsingInlineBuffer(true)
+            , m_markSet(0)
 #ifndef NDEBUG
             , m_isReadOnly(false)
 #endif
@@ -54,9 +55,10 @@ namespace JSC {
         }
 
         // Constructor for a read-only list whose data has already been allocated elsewhere.
-        ArgList(Register* buffer, size_t size)
+        MarkedArgumentBuffer(Register* buffer, size_t size)
             : m_buffer(buffer)
             , m_size(size)
+            , m_isUsingInlineBuffer(true)
             , m_markSet(0)
 #ifndef NDEBUG
             , m_isReadOnly(true)
@@ -76,7 +78,7 @@ namespace JSC {
 #endif
         }
 
-        ~ArgList()
+        ~MarkedArgumentBuffer()
         {
             if (m_markSet)
                 m_markSet->remove(this);
@@ -85,10 +87,10 @@ namespace JSC {
         size_t size() const { return m_size; }
         bool isEmpty() const { return !m_size; }
 
-        JSValuePtr at(ExecState* exec, size_t i) const
+        JSValue at(size_t i) const
         {
             if (i < m_size)
-                return m_buffer[i].jsValue(exec);
+                return m_buffer[i].jsValue();
             return jsUndefined();
         }
 
@@ -99,11 +101,15 @@ namespace JSC {
             m_size = 0;
         }
 
-        void append(JSValuePtr v)
+        void append(JSValue v)
         {
             ASSERT(!m_isReadOnly);
-            
-            if (m_size < inlineCapacity) {
+
+#if ENABLE(JSC_ZOMBIES)
+            ASSERT(!v.isZombie());
+#endif
+
+            if (m_isUsingInlineBuffer && m_size < inlineCapacity) {
                 m_vector.uncheckedAppend(v);
                 ++m_size;
             } else {
@@ -111,24 +117,37 @@ namespace JSC {
                 // the performance of the fast "just append to inline buffer" case.
                 slowAppend(v);
                 ++m_size;
+                m_isUsingInlineBuffer = false;
             }
         }
 
-        void getSlice(int startIndex, ArgList& result) const;
+        void removeLast()
+        { 
+            ASSERT(m_size);
+            m_size--;
+            m_vector.removeLast();
+        }
 
+        JSValue last() 
+        {
+            ASSERT(m_size);
+            return m_buffer[m_size - 1].jsValue();
+        }
+        
         iterator begin() { return m_buffer; }
         iterator end() { return m_buffer + m_size; }
 
         const_iterator begin() const { return m_buffer; }
         const_iterator end() const { return m_buffer + m_size; }
 
-        static void markLists(ListSet&);
+        static void markLists(MarkStack&, ListSet&);
 
     private:
-        void slowAppend(JSValuePtr);
+        void slowAppend(JSValue);
         
         Register* m_buffer;
         size_t m_size;
+        bool m_isUsingInlineBuffer;
 
         VectorType m_vector;
         ListSet* m_markSet;
@@ -156,6 +175,64 @@ namespace JSC {
         void operator delete(void*, size_t);
     };
 
+    class ArgList {
+        friend class JIT;
+    public:
+        typedef JSValue* iterator;
+        typedef const JSValue* const_iterator;
+
+        ArgList()
+            : m_args(0)
+            , m_argCount(0)
+        {
+        }
+        
+        ArgList(JSValue* args, unsigned argCount)
+            : m_args(args)
+            , m_argCount(argCount)
+        {
+#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