Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / runtime / ArgList.h
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2003-2017 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 #pragma once
23
24 #include "CallFrame.h"
25 #include <wtf/ForbidHeapAllocation.h>
26 #include <wtf/HashSet.h>
27
28 namespace JSC {
29
30 class MarkedArgumentBuffer {
31     WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
32     WTF_FORBID_HEAP_ALLOCATION;
33     friend class VM;
34     friend class ArgList;
35
36 private:
37     static const size_t inlineCapacity = 8;
38     typedef HashSet<MarkedArgumentBuffer*> ListSet;
39
40 public:
41     // Constructor for a read-write list, to which you may append values.
42     // FIXME: Remove all clients of this API, then remove this API.
43     MarkedArgumentBuffer()
44         : m_size(0)
45         , m_capacity(inlineCapacity)
46         , m_buffer(m_inlineBuffer)
47         , m_markSet(0)
48     {
49     }
50
51     ~MarkedArgumentBuffer()
52     {
53         if (m_markSet)
54             m_markSet->remove(this);
55
56         if (EncodedJSValue* base = mallocBase())
57             fastFree(base);
58     }
59
60     size_t size() const { return m_size; }
61     bool isEmpty() const { return !m_size; }
62
63     JSValue at(int i) const
64     {
65         if (i >= m_size)
66             return jsUndefined();
67
68         return JSValue::decode(slotFor(i));
69     }
70
71     void clear()
72     {
73         m_size = 0;
74     }
75
76     void append(JSValue v)
77     {
78         ASSERT(m_size <= m_capacity);
79         if (m_size == m_capacity || mallocBase())
80             return slowAppend(v);
81
82         slotFor(m_size) = JSValue::encode(v);
83         ++m_size;
84     }
85
86     void removeLast()
87     { 
88         ASSERT(m_size);
89         m_size--;
90     }
91
92     JSValue last() 
93     {
94         ASSERT(m_size);
95         return JSValue::decode(slotFor(m_size - 1));
96     }
97         
98     static void markLists(SlotVisitor&, ListSet&);
99
100     void ensureCapacity(size_t requestedCapacity)
101     {
102         if (requestedCapacity > static_cast<size_t>(m_capacity))
103             slowEnsureCapacity(requestedCapacity);
104     }
105
106 private:
107     void expandCapacity();
108     void expandCapacity(int newCapacity);
109     void slowEnsureCapacity(size_t requestedCapacity);
110
111     void addMarkSet(JSValue);
112
113     JS_EXPORT_PRIVATE void slowAppend(JSValue);
114         
115     EncodedJSValue& slotFor(int item) const
116     {
117         return m_buffer[item];
118     }
119         
120     EncodedJSValue* mallocBase()
121     {
122         if (m_buffer == m_inlineBuffer)
123             return 0;
124         return &slotFor(0);
125     }
126         
127     int m_size;
128     int m_capacity;
129     EncodedJSValue m_inlineBuffer[inlineCapacity];
130     EncodedJSValue* m_buffer;
131     ListSet* m_markSet;
132 };
133
134 class ArgList {
135     friend class Interpreter;
136     friend class JIT;
137 public:
138     ArgList()
139         : m_args(0)
140         , m_argCount(0)
141     {
142     }
143
144     ArgList(ExecState* exec)
145         : m_args(reinterpret_cast<JSValue*>(&exec[CallFrame::argumentOffset(0)]))
146         , m_argCount(exec->argumentCount())
147     {
148     }
149
150     ArgList(const MarkedArgumentBuffer& args)
151         : m_args(reinterpret_cast<JSValue*>(args.m_buffer))
152         , m_argCount(args.size())
153     {
154     }
155
156     JSValue at(int i) const
157     {
158         if (i >= m_argCount)
159             return jsUndefined();
160         return m_args[i];
161     }
162
163     bool isEmpty() const { return !m_argCount; }
164     size_t size() const { return m_argCount; }
165         
166     JS_EXPORT_PRIVATE void getSlice(int startIndex, ArgList& result) const;
167
168     // FIXME: This is only made public as a work around for jsc's test helper function,
169     // callWasmFunction() to use. Make this a private method again once we can remove
170     // callWasmFunction().
171     // https://bugs.webkit.org/show_bug.cgi?id=168582
172     JSValue* data() const { return m_args; }
173
174 private:
175     JSValue* m_args;
176     int m_argCount;
177 };
178
179 } // namespace JSC