CachedCall should let GC know to keep its arguments alive.
[WebKit-https.git] / Source / JavaScriptCore / interpreter / CallFrame.h
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #pragma once
24
25 #include "AbstractPC.h"
26 #include "MacroAssemblerCodeRef.h"
27 #include "Register.h"
28 #include "StackVisitor.h"
29 #include "VM.h"
30 #include "VMEntryRecord.h"
31
32 namespace JSC  {
33
34     class Arguments;
35     class ExecState;
36     class Interpreter;
37     class JSCallee;
38     class JSScope;
39
40     struct Instruction;
41
42     typedef ExecState CallFrame;
43
44     struct CallSiteIndex {
45         CallSiteIndex()
46             : m_bits(UINT_MAX)
47         {
48         }
49         
50         explicit CallSiteIndex(uint32_t bits)
51             : m_bits(bits)
52         { }
53 #if USE(JSVALUE32_64)
54         explicit CallSiteIndex(Instruction* instruction)
55             : m_bits(bitwise_cast<uint32_t>(instruction))
56         { }
57 #endif
58
59         explicit operator bool() const { return m_bits != UINT_MAX; }
60         bool operator==(const CallSiteIndex& other) const { return m_bits == other.m_bits; }
61         
62         inline uint32_t bits() const { return m_bits; }
63
64     private:
65         uint32_t m_bits;
66     };
67
68     struct CallerFrameAndPC {
69         CallFrame* callerFrame;
70         Instruction* pc;
71         static const int sizeInRegisters = 2 * sizeof(void*) / sizeof(Register);
72     };
73     static_assert(CallerFrameAndPC::sizeInRegisters == sizeof(CallerFrameAndPC) / sizeof(Register), "CallerFrameAndPC::sizeInRegisters is incorrect.");
74
75     struct CallFrameSlot {
76         static const int codeBlock = CallerFrameAndPC::sizeInRegisters;
77         static const int callee = codeBlock + 1;
78         static const int argumentCount = callee + 1;
79         static const int thisArgument = argumentCount + 1;
80         static const int firstArgument = thisArgument + 1;
81     };
82
83     // Represents the current state of script execution.
84     // Passed as the first argument to most functions.
85     class ExecState : private Register {
86     public:
87         static const int headerSizeInRegisters = CallFrameSlot::argumentCount + 1;
88
89         JSValue calleeAsValue() const { return this[CallFrameSlot::callee].jsValue(); }
90         JSObject* jsCallee() const { return this[CallFrameSlot::callee].object(); }
91         JSCell* callee() const { return this[CallFrameSlot::callee].unboxedCell(); }
92         SUPPRESS_ASAN JSValue unsafeCallee() const { return this[CallFrameSlot::callee].asanUnsafeJSValue(); }
93         CodeBlock* codeBlock() const { return this[CallFrameSlot::codeBlock].Register::codeBlock(); }
94         CodeBlock** addressOfCodeBlock() const { return bitwise_cast<CodeBlock**>(this + CallFrameSlot::codeBlock); }
95         SUPPRESS_ASAN CodeBlock* unsafeCodeBlock() const { return this[CallFrameSlot::codeBlock].Register::asanUnsafeCodeBlock(); }
96         JSScope* scope(int scopeRegisterOffset) const
97         {
98             ASSERT(this[scopeRegisterOffset].Register::scope());
99             return this[scopeRegisterOffset].Register::scope();
100         }
101
102         // Global object in which execution began.
103         JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject();
104
105         // Global object in which the currently executing code was defined.
106         // Differs from vmEntryGlobalObject() during function calls across web browser frames.
107         JSGlobalObject* lexicalGlobalObject() const;
108
109         // Differs from lexicalGlobalObject because this will have DOM window shell rather than
110         // the actual DOM window, which can't be "this" for security reasons.
111         JSObject* globalThisValue() const;
112
113         VM& vm() const;
114
115         // Convenience functions for access to global data.
116         // It takes a few memory references to get from a call frame to the global data
117         // pointer, so these are inefficient, and should be used sparingly in new code.
118         // But they're used in many places in legacy code, so they're not going away any time soon.
119
120         AtomicStringTable* atomicStringTable() const { return vm().atomicStringTable(); }
121         const CommonIdentifiers& propertyNames() const { return *vm().propertyNames; }
122         const ArgList& emptyList() const { return *vm().emptyList; }
123         Interpreter* interpreter() { return vm().interpreter; }
124         Heap* heap() { return &vm().heap; }
125
126
127         static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
128         Register* registers() { return this; }
129         const Register* registers() const { return this; }
130
131         CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
132
133         CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); }
134         void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
135         SUPPRESS_ASAN void* unsafeCallerFrameOrVMEntryFrame() const { return unsafeCallerFrameAndPC().callerFrame; }
136
137         CallFrame* unsafeCallerFrame(VMEntryFrame*&);
138         JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&);
139
140         JS_EXPORT_PRIVATE SourceOrigin callerSourceOrigin();
141
142         static ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); }
143
144         ReturnAddressPtr returnPC() const { return ReturnAddressPtr(callerFrameAndPC().pc); }
145         bool hasReturnPC() const { return !!callerFrameAndPC().pc; }
146         void clearReturnPC() { callerFrameAndPC().pc = 0; }
147         static ptrdiff_t returnPCOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, pc); }
148         AbstractPC abstractReturnPC(VM& vm) { return AbstractPC(vm, this); }
149
150         bool callSiteBitsAreBytecodeOffset() const;
151         bool callSiteBitsAreCodeOriginIndex() const;
152
153         unsigned callSiteAsRawBits() const;
154         unsigned unsafeCallSiteAsRawBits() const;
155         CallSiteIndex callSiteIndex() const;
156         CallSiteIndex unsafeCallSiteIndex() const;
157     private:
158         unsigned callSiteBitsAsBytecodeOffset() const;
159     public:
160
161         // This will try to get you the bytecode offset, but you should be aware that
162         // this bytecode offset may be bogus in the presence of inlining. This will
163         // also return 0 if the call frame has no notion of bytecode offsets (for
164         // example if it's native code).
165         // https://bugs.webkit.org/show_bug.cgi?id=121754
166         unsigned bytecodeOffset();
167         
168         // This will get you a CodeOrigin. It will always succeed. May return
169         // CodeOrigin(0) if we're in native code.
170         JS_EXPORT_PRIVATE CodeOrigin codeOrigin();
171
172         Register* topOfFrame()
173         {
174             if (!codeBlock())
175                 return registers();
176             return topOfFrameInternal();
177         }
178     
179         Instruction* currentVPC() const; // This only makes sense in the LLInt and baseline.
180         void setCurrentVPC(Instruction* vpc);
181
182         void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; }
183         void setScope(int scopeRegisterOffset, JSScope* scope) { static_cast<Register*>(this)[scopeRegisterOffset] = scope; }
184
185         static void initGlobalExec(ExecState* globalExec, JSCallee* globalCallee);
186
187         // Read a register from the codeframe (or constant from the CodeBlock).
188         Register& r(int);
189         Register& r(VirtualRegister);
190         // Read a register for a non-constant
191         Register& uncheckedR(int);
192         Register& uncheckedR(VirtualRegister);
193
194         // Access to arguments as passed. (After capture, arguments may move to a different location.)
195         size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
196         size_t argumentCountIncludingThis() const { return this[CallFrameSlot::argumentCount].payload(); }
197         static int argumentOffset(int argument) { return (CallFrameSlot::firstArgument + argument); }
198         static int argumentOffsetIncludingThis(int argument) { return (CallFrameSlot::thisArgument + argument); }
199
200         // In the following (argument() and setArgument()), the 'argument'
201         // parameter is the index of the arguments of the target function of
202         // this frame. The index starts at 0 for the first arg, 1 for the
203         // second, etc.
204         //
205         // The arguments (in this case) do not include the 'this' value.
206         // arguments(0) will not fetch the 'this' value. To get/set 'this',
207         // use thisValue() and setThisValue() below.
208
209         JSValue* addressOfArgumentsStart() const { return bitwise_cast<JSValue*>(this + argumentOffset(0)); }
210         JSValue argument(size_t argument)
211         {
212             if (argument >= argumentCount())
213                  return jsUndefined();
214             return getArgumentUnsafe(argument);
215         }
216         JSValue uncheckedArgument(size_t argument)
217         {
218             ASSERT(argument < argumentCount());
219             return getArgumentUnsafe(argument);
220         }
221         void setArgument(size_t argument, JSValue value)
222         {
223             this[argumentOffset(argument)] = value;
224         }
225
226         JSValue getArgumentUnsafe(size_t argIndex)
227         {
228             // User beware! This method does not verify that there is a valid
229             // argument at the specified argIndex. This is used for debugging
230             // and verification code only. The caller is expected to know what
231             // he/she is doing when calling this method.
232             return this[argumentOffset(argIndex)].jsValue();
233         }
234
235         static int thisArgumentOffset() { return argumentOffsetIncludingThis(0); }
236         JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
237         void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
238
239         // Under the constructor implemented in C++, thisValue holds the newTarget instead of the automatically constructed value.
240         // The result of this function is only effective under the "construct" context.
241         JSValue newTarget() { return thisValue(); }
242
243         JSValue argumentAfterCapture(size_t argument);
244
245         static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + CallFrameSlot::thisArgument - 1; }
246
247         static CallFrame* noCaller() { return 0; }
248
249         void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[CallFrameSlot::argumentCount].payload() = count; }
250         void setCallee(JSObject* callee) { static_cast<Register*>(this)[CallFrameSlot::callee] = callee; }
251         void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[CallFrameSlot::codeBlock] = codeBlock; }
252         void setReturnPC(void* value) { callerFrameAndPC().pc = reinterpret_cast<Instruction*>(value); }
253
254         String friendlyFunctionName();
255
256         // CallFrame::iterate() expects a Functor that implements the following method:
257         //     StackVisitor::Status operator()(StackVisitor&) const;
258         // FIXME: This method is improper. We rely on the fact that we can call it with a null
259         // receiver. We should always be using StackVisitor directly.
260         template <typename Functor> void iterate(const Functor& functor)
261         {
262             StackVisitor::visit<Functor>(this, functor);
263         }
264
265         void dump(PrintStream&);
266         JS_EXPORT_PRIVATE const char* describeFrame();
267
268     private:
269
270         ExecState();
271         ~ExecState();
272
273         Register* topOfFrameInternal();
274
275         // The following are for internal use in debugging and verification
276         // code only and not meant as an API for general usage:
277
278         size_t argIndexForRegister(Register* reg)
279         {
280             // The register at 'offset' number of slots from the frame pointer
281             // i.e.
282             //       reg = frame[offset];
283             //   ==> reg = frame + offset;
284             //   ==> offset = reg - frame;
285             int offset = reg - this->registers();
286
287             // The offset is defined (based on argumentOffset()) to be:
288             //       offset = CallFrameSlot::firstArgument - argIndex;
289             // Hence:
290             //       argIndex = CallFrameSlot::firstArgument - offset;
291             size_t argIndex = offset - CallFrameSlot::firstArgument;
292             return argIndex;
293         }
294
295         CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); }
296         const CallerFrameAndPC& callerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
297         SUPPRESS_ASAN const CallerFrameAndPC& unsafeCallerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
298     };
299
300 } // namespace JSC