2ea54370a43e6a18c51d53ab557f0f9cea2e1223
[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 "CalleeBits.h"
27 #include "MacroAssemblerCodeRef.h"
28 #include "Register.h"
29 #include "StackVisitor.h"
30 #include "VM.h"
31 #include "VMEntryRecord.h"
32
33 namespace JSC  {
34
35     class Arguments;
36     class ExecState;
37     class Interpreter;
38     class JSCallee;
39     class JSScope;
40
41     struct Instruction;
42
43     typedef ExecState CallFrame;
44
45     struct CallSiteIndex {
46         CallSiteIndex()
47             : m_bits(UINT_MAX)
48         {
49         }
50         
51         explicit CallSiteIndex(uint32_t bits)
52             : m_bits(bits)
53         { }
54 #if USE(JSVALUE32_64)
55         explicit CallSiteIndex(Instruction* instruction)
56             : m_bits(bitwise_cast<uint32_t>(instruction))
57         { }
58 #endif
59
60         explicit operator bool() const { return m_bits != UINT_MAX; }
61         bool operator==(const CallSiteIndex& other) const { return m_bits == other.m_bits; }
62         
63         inline uint32_t bits() const { return m_bits; }
64
65     private:
66         uint32_t m_bits;
67     };
68
69     struct CallerFrameAndPC {
70         CallFrame* callerFrame;
71         Instruction* pc;
72         static const int sizeInRegisters = 2 * sizeof(void*) / sizeof(Register);
73     };
74     static_assert(CallerFrameAndPC::sizeInRegisters == sizeof(CallerFrameAndPC) / sizeof(Register), "CallerFrameAndPC::sizeInRegisters is incorrect.");
75
76     struct CallFrameSlot {
77         static const int codeBlock = CallerFrameAndPC::sizeInRegisters;
78         static const int callee = codeBlock + 1;
79         static const int argumentCount = callee + 1;
80         static const int thisArgument = argumentCount + 1;
81         static const int firstArgument = thisArgument + 1;
82     };
83
84     // Represents the current state of script execution.
85     // Passed as the first argument to most functions.
86     class ExecState : private Register {
87     public:
88         static const int headerSizeInRegisters = CallFrameSlot::argumentCount + 1;
89
90         // This function should only be called in very specific circumstances
91         // when you've guaranteed the callee can't be a Wasm callee, and can
92         // be an arbitrary JSValue. This function should basically never be used.
93         // Its only use right now is when we are making a call, and we're not
94         // yet sure if the callee is a cell. In general, a JS callee is guaranteed
95         // to be a cell, however, there is a brief window where we need to check
96         // to see if it's a cell, and if it's not, we throw an exception.
97         JSValue guaranteedJSValueCallee() const
98         {
99             ASSERT(!callee().isWasm());
100             return this[CallFrameSlot::callee].jsValue();
101         }
102         JSObject* jsCallee() const
103         {
104             ASSERT(!callee().isWasm());
105             return this[CallFrameSlot::callee].object();
106         }
107         CalleeBits callee() const { return CalleeBits(this[CallFrameSlot::callee].pointer()); }
108         SUPPRESS_ASAN CalleeBits unsafeCallee() const { return CalleeBits(this[CallFrameSlot::callee].pointer()); }
109         CodeBlock* codeBlock() const { return this[CallFrameSlot::codeBlock].Register::codeBlock(); }
110         CodeBlock** addressOfCodeBlock() const { return bitwise_cast<CodeBlock**>(this + CallFrameSlot::codeBlock); }
111         SUPPRESS_ASAN CodeBlock* unsafeCodeBlock() const { return this[CallFrameSlot::codeBlock].Register::asanUnsafeCodeBlock(); }
112         JSScope* scope(int scopeRegisterOffset) const
113         {
114             ASSERT(this[scopeRegisterOffset].Register::scope());
115             return this[scopeRegisterOffset].Register::scope();
116         }
117         // Global object in which execution began.
118         // This variant is not safe to call from a Wasm frame.
119         JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject();
120         // This variant is safe to call from a Wasm frame.
121         JSGlobalObject* vmEntryGlobalObject(VM&);
122
123         JSGlobalObject* wasmAwareLexicalGlobalObject(VM&);
124
125         bool isAnyWasmCallee();
126
127         // Global object in which the currently executing code was defined.
128         // Differs from vmEntryGlobalObject() during function calls across web browser frames.
129         JSGlobalObject* lexicalGlobalObject() const;
130
131         // Differs from lexicalGlobalObject because this will have DOM window shell rather than
132         // the actual DOM window, which can't be "this" for security reasons.
133         JSObject* globalThisValue() const;
134
135         VM& vm() const;
136
137         // Convenience functions for access to global data.
138         // It takes a few memory references to get from a call frame to the global data
139         // pointer, so these are inefficient, and should be used sparingly in new code.
140         // But they're used in many places in legacy code, so they're not going away any time soon.
141
142         AtomicStringTable* atomicStringTable() const { return vm().atomicStringTable(); }
143         const CommonIdentifiers& propertyNames() const { return *vm().propertyNames; }
144         const ArgList& emptyList() const { return *vm().emptyList; }
145         Interpreter* interpreter() { return vm().interpreter; }
146         Heap* heap() { return &vm().heap; }
147
148
149         static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
150         Register* registers() { return this; }
151         const Register* registers() const { return this; }
152
153         CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
154
155         CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); }
156         void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; }
157         SUPPRESS_ASAN void* unsafeCallerFrameOrVMEntryFrame() const { return unsafeCallerFrameAndPC().callerFrame; }
158
159         CallFrame* unsafeCallerFrame(VMEntryFrame*&);
160         JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&);
161
162         JS_EXPORT_PRIVATE SourceOrigin callerSourceOrigin();
163
164         static ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); }
165
166         ReturnAddressPtr returnPC() const { return ReturnAddressPtr(callerFrameAndPC().pc); }
167         bool hasReturnPC() const { return !!callerFrameAndPC().pc; }
168         void clearReturnPC() { callerFrameAndPC().pc = 0; }
169         static ptrdiff_t returnPCOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, pc); }
170         AbstractPC abstractReturnPC(VM& vm) { return AbstractPC(vm, this); }
171
172         bool callSiteBitsAreBytecodeOffset() const;
173         bool callSiteBitsAreCodeOriginIndex() const;
174
175         unsigned callSiteAsRawBits() const;
176         unsigned unsafeCallSiteAsRawBits() const;
177         CallSiteIndex callSiteIndex() const;
178         CallSiteIndex unsafeCallSiteIndex() const;
179     private:
180         unsigned callSiteBitsAsBytecodeOffset() const;
181     public:
182
183         // This will try to get you the bytecode offset, but you should be aware that
184         // this bytecode offset may be bogus in the presence of inlining. This will
185         // also return 0 if the call frame has no notion of bytecode offsets (for
186         // example if it's native code).
187         // https://bugs.webkit.org/show_bug.cgi?id=121754
188         unsigned bytecodeOffset();
189         
190         // This will get you a CodeOrigin. It will always succeed. May return
191         // CodeOrigin(0) if we're in native code.
192         JS_EXPORT_PRIVATE CodeOrigin codeOrigin();
193
194         Register* topOfFrame()
195         {
196             if (!codeBlock())
197                 return registers();
198             return topOfFrameInternal();
199         }
200     
201         Instruction* currentVPC() const; // This only makes sense in the LLInt and baseline.
202         void setCurrentVPC(Instruction* vpc);
203
204         void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; }
205         void setScope(int scopeRegisterOffset, JSScope* scope) { static_cast<Register*>(this)[scopeRegisterOffset] = scope; }
206
207         static void initGlobalExec(ExecState* globalExec, JSCallee* globalCallee);
208
209         // Read a register from the codeframe (or constant from the CodeBlock).
210         Register& r(int);
211         Register& r(VirtualRegister);
212         // Read a register for a non-constant
213         Register& uncheckedR(int);
214         Register& uncheckedR(VirtualRegister);
215
216         // Access to arguments as passed. (After capture, arguments may move to a different location.)
217         size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
218         size_t argumentCountIncludingThis() const { return this[CallFrameSlot::argumentCount].payload(); }
219         static int argumentOffset(int argument) { return (CallFrameSlot::firstArgument + argument); }
220         static int argumentOffsetIncludingThis(int argument) { return (CallFrameSlot::thisArgument + argument); }
221
222         // In the following (argument() and setArgument()), the 'argument'
223         // parameter is the index of the arguments of the target function of
224         // this frame. The index starts at 0 for the first arg, 1 for the
225         // second, etc.
226         //
227         // The arguments (in this case) do not include the 'this' value.
228         // arguments(0) will not fetch the 'this' value. To get/set 'this',
229         // use thisValue() and setThisValue() below.
230
231         JSValue* addressOfArgumentsStart() const { return bitwise_cast<JSValue*>(this + argumentOffset(0)); }
232         JSValue argument(size_t argument)
233         {
234             if (argument >= argumentCount())
235                  return jsUndefined();
236             return getArgumentUnsafe(argument);
237         }
238         JSValue uncheckedArgument(size_t argument)
239         {
240             ASSERT(argument < argumentCount());
241             return getArgumentUnsafe(argument);
242         }
243         void setArgument(size_t argument, JSValue value)
244         {
245             this[argumentOffset(argument)] = value;
246         }
247
248         JSValue getArgumentUnsafe(size_t argIndex)
249         {
250             // User beware! This method does not verify that there is a valid
251             // argument at the specified argIndex. This is used for debugging
252             // and verification code only. The caller is expected to know what
253             // he/she is doing when calling this method.
254             return this[argumentOffset(argIndex)].jsValue();
255         }
256
257         static int thisArgumentOffset() { return argumentOffsetIncludingThis(0); }
258         JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
259         void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
260
261         // Under the constructor implemented in C++, thisValue holds the newTarget instead of the automatically constructed value.
262         // The result of this function is only effective under the "construct" context.
263         JSValue newTarget() { return thisValue(); }
264
265         JSValue argumentAfterCapture(size_t argument);
266
267         static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + CallFrameSlot::thisArgument - 1; }
268
269         static CallFrame* noCaller() { return 0; }
270
271         void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[CallFrameSlot::argumentCount].payload() = count; }
272         void setCallee(JSObject* callee) { static_cast<Register*>(this)[CallFrameSlot::callee] = callee; }
273         void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[CallFrameSlot::codeBlock] = codeBlock; }
274         void setReturnPC(void* value) { callerFrameAndPC().pc = reinterpret_cast<Instruction*>(value); }
275
276         String friendlyFunctionName();
277
278         // CallFrame::iterate() expects a Functor that implements the following method:
279         //     StackVisitor::Status operator()(StackVisitor&) const;
280         // FIXME: This method is improper. We rely on the fact that we can call it with a null
281         // receiver. We should always be using StackVisitor directly.
282         // It's only valid to call this from a non-wasm top frame.
283         template <typename Functor> void iterate(const Functor& functor)
284         {
285             VM* vm;
286             void* rawThis = this;
287             if (!!rawThis) {
288                 RELEASE_ASSERT(callee().isCell());
289                 vm = &this->vm();
290             } else
291                 vm = nullptr;
292             StackVisitor::visit<Functor>(this, vm, functor);
293         }
294
295         void dump(PrintStream&);
296         JS_EXPORT_PRIVATE const char* describeFrame();
297
298     private:
299
300         ExecState();
301         ~ExecState();
302
303         Register* topOfFrameInternal();
304
305         // The following are for internal use in debugging and verification
306         // code only and not meant as an API for general usage:
307
308         size_t argIndexForRegister(Register* reg)
309         {
310             // The register at 'offset' number of slots from the frame pointer
311             // i.e.
312             //       reg = frame[offset];
313             //   ==> reg = frame + offset;
314             //   ==> offset = reg - frame;
315             int offset = reg - this->registers();
316
317             // The offset is defined (based on argumentOffset()) to be:
318             //       offset = CallFrameSlot::firstArgument - argIndex;
319             // Hence:
320             //       argIndex = CallFrameSlot::firstArgument - offset;
321             size_t argIndex = offset - CallFrameSlot::firstArgument;
322             return argIndex;
323         }
324
325         CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); }
326         const CallerFrameAndPC& callerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
327         SUPPRESS_ASAN const CallerFrameAndPC& unsafeCallerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); }
328     };
329
330 } // namespace JSC