]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/CommonSlowPaths.h
JavaScriptCore-7600.1.4.11.8.tar.gz
[apple/javascriptcore.git] / runtime / CommonSlowPaths.h
1 /*
2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef CommonSlowPaths_h
27 #define CommonSlowPaths_h
28
29 #include "CodeBlock.h"
30 #include "CodeSpecializationKind.h"
31 #include "ExceptionHelpers.h"
32 #include "JSStackInlines.h"
33 #include "NameInstance.h"
34 #include "StackAlignment.h"
35 #include "VM.h"
36 #include <wtf/StdLibExtras.h>
37
38 namespace JSC {
39
40 // The purpose of this namespace is to include slow paths that are shared
41 // between the interpreter and baseline JIT. They are written to be agnostic
42 // with respect to the slow-path calling convention, but they do rely on the
43 // JS code being executed more-or-less directly from bytecode (so the call
44 // frame layout is unmodified, making it potentially awkward to use these
45 // from any optimizing JIT, like the DFG).
46
47 namespace CommonSlowPaths {
48
49 struct ArityCheckData {
50 unsigned paddedStackSpace;
51 void* thunkToCall;
52 void* returnPC;
53 };
54
55 ALWAYS_INLINE int arityCheckFor(ExecState* exec, JSStack* stack, CodeSpecializationKind kind)
56 {
57 JSFunction* callee = jsCast<JSFunction*>(exec->callee());
58 ASSERT(!callee->isHostFunction());
59 CodeBlock* newCodeBlock = callee->jsExecutable()->codeBlockFor(kind);
60 int argumentCountIncludingThis = exec->argumentCountIncludingThis();
61
62 ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters());
63 int missingArgumentCount = newCodeBlock->numParameters() - argumentCountIncludingThis;
64 int neededStackSpace = missingArgumentCount + 1; // Allow space to save the original return PC.
65 int paddedStackSpace = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), neededStackSpace);
66
67 if (!stack->ensureCapacityFor(exec->registers() - paddedStackSpace))
68 return -1;
69 return paddedStackSpace / stackAlignmentRegisters();
70 }
71
72 inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal)
73 {
74 if (!baseVal.isObject()) {
75 exec->vm().throwException(exec, createInvalidParameterError(exec, "in", baseVal));
76 return false;
77 }
78
79 JSObject* baseObj = asObject(baseVal);
80
81 uint32_t i;
82 if (propName.getUInt32(i))
83 return baseObj->hasProperty(exec, i);
84
85 if (isName(propName))
86 return baseObj->hasProperty(exec, jsCast<NameInstance*>(propName.asCell())->privateName());
87
88 Identifier property(exec, propName.toString(exec)->value(exec));
89 if (exec->vm().exception())
90 return false;
91 return baseObj->hasProperty(exec, property);
92 }
93
94 } // namespace CommonSlowPaths
95
96 class ExecState;
97 struct Instruction;
98
99 #if USE(JSVALUE64)
100 // According to C++ rules, a type used for the return signature of function with C linkage (i.e.
101 // 'extern "C"') needs to be POD; hence putting any constructors into it could cause either compiler
102 // warnings, or worse, a change in the ABI used to return these types.
103 struct SlowPathReturnType {
104 void* a;
105 void* b;
106 };
107
108 inline SlowPathReturnType encodeResult(void* a, void* b)
109 {
110 SlowPathReturnType result;
111 result.a = a;
112 result.b = b;
113 return result;
114 }
115
116 inline void decodeResult(SlowPathReturnType result, void*& a, void*& b)
117 {
118 a = result.a;
119 b = result.b;
120 }
121
122 #else // USE(JSVALUE32_64)
123 typedef int64_t SlowPathReturnType;
124
125 typedef union {
126 struct {
127 void* a;
128 void* b;
129 } pair;
130 int64_t i;
131 } SlowPathReturnTypeEncoding;
132
133 inline SlowPathReturnType encodeResult(void* a, void* b)
134 {
135 SlowPathReturnTypeEncoding u;
136 u.pair.a = a;
137 u.pair.b = b;
138 return u.i;
139 }
140
141 inline void decodeResult(SlowPathReturnType result, void*& a, void*& b)
142 {
143 SlowPathReturnTypeEncoding u;
144 u.i = result;
145 a = u.pair.a;
146 b = u.pair.b;
147 }
148 #endif // USE(JSVALUE32_64)
149
150 #define SLOW_PATH
151
152 #define SLOW_PATH_DECL(name) \
153 extern "C" SlowPathReturnType SLOW_PATH name(ExecState* exec, Instruction* pc)
154
155 #define SLOW_PATH_HIDDEN_DECL(name) \
156 SLOW_PATH_DECL(name) WTF_INTERNAL
157
158 SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck);
159 SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck);
160 SLOW_PATH_HIDDEN_DECL(slow_path_touch_entry);
161 SLOW_PATH_HIDDEN_DECL(slow_path_create_arguments);
162 SLOW_PATH_HIDDEN_DECL(slow_path_create_this);
163 SLOW_PATH_HIDDEN_DECL(slow_path_enter);
164 SLOW_PATH_HIDDEN_DECL(slow_path_get_callee);
165 SLOW_PATH_HIDDEN_DECL(slow_path_to_this);
166 SLOW_PATH_HIDDEN_DECL(slow_path_captured_mov);
167 SLOW_PATH_HIDDEN_DECL(slow_path_new_captured_func);
168 SLOW_PATH_HIDDEN_DECL(slow_path_not);
169 SLOW_PATH_HIDDEN_DECL(slow_path_eq);
170 SLOW_PATH_HIDDEN_DECL(slow_path_neq);
171 SLOW_PATH_HIDDEN_DECL(slow_path_stricteq);
172 SLOW_PATH_HIDDEN_DECL(slow_path_nstricteq);
173 SLOW_PATH_HIDDEN_DECL(slow_path_less);
174 SLOW_PATH_HIDDEN_DECL(slow_path_lesseq);
175 SLOW_PATH_HIDDEN_DECL(slow_path_greater);
176 SLOW_PATH_HIDDEN_DECL(slow_path_greatereq);
177 SLOW_PATH_HIDDEN_DECL(slow_path_inc);
178 SLOW_PATH_HIDDEN_DECL(slow_path_dec);
179 SLOW_PATH_HIDDEN_DECL(slow_path_to_number);
180 SLOW_PATH_HIDDEN_DECL(slow_path_negate);
181 SLOW_PATH_HIDDEN_DECL(slow_path_add);
182 SLOW_PATH_HIDDEN_DECL(slow_path_mul);
183 SLOW_PATH_HIDDEN_DECL(slow_path_sub);
184 SLOW_PATH_HIDDEN_DECL(slow_path_div);
185 SLOW_PATH_HIDDEN_DECL(slow_path_mod);
186 SLOW_PATH_HIDDEN_DECL(slow_path_lshift);
187 SLOW_PATH_HIDDEN_DECL(slow_path_rshift);
188 SLOW_PATH_HIDDEN_DECL(slow_path_urshift);
189 SLOW_PATH_HIDDEN_DECL(slow_path_unsigned);
190 SLOW_PATH_HIDDEN_DECL(slow_path_bitand);
191 SLOW_PATH_HIDDEN_DECL(slow_path_bitor);
192 SLOW_PATH_HIDDEN_DECL(slow_path_bitxor);
193 SLOW_PATH_HIDDEN_DECL(slow_path_typeof);
194 SLOW_PATH_HIDDEN_DECL(slow_path_is_object);
195 SLOW_PATH_HIDDEN_DECL(slow_path_is_function);
196 SLOW_PATH_HIDDEN_DECL(slow_path_in);
197 SLOW_PATH_HIDDEN_DECL(slow_path_del_by_val);
198 SLOW_PATH_HIDDEN_DECL(slow_path_strcat);
199 SLOW_PATH_HIDDEN_DECL(slow_path_to_primitive);
200
201 } // namespace JSC
202
203 #endif // CommonSlowPaths_h