2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef CommonSlowPaths_h
27 #define CommonSlowPaths_h
29 #include "CodeBlock.h"
30 #include "CodeSpecializationKind.h"
31 #include "ExceptionHelpers.h"
32 #include "JSStackInlines.h"
33 #include "NameInstance.h"
34 #include "StackAlignment.h"
36 #include <wtf/StdLibExtras.h>
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).
47 namespace CommonSlowPaths
{
49 struct ArityCheckData
{
50 unsigned paddedStackSpace
;
55 ALWAYS_INLINE
int arityCheckFor(ExecState
* exec
, JSStack
* stack
, CodeSpecializationKind kind
)
57 JSFunction
* callee
= jsCast
<JSFunction
*>(exec
->callee());
58 ASSERT(!callee
->isHostFunction());
59 CodeBlock
* newCodeBlock
= callee
->jsExecutable()->codeBlockFor(kind
);
60 int argumentCountIncludingThis
= exec
->argumentCountIncludingThis();
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
);
67 if (!stack
->ensureCapacityFor(exec
->registers() - paddedStackSpace
))
69 return paddedStackSpace
/ stackAlignmentRegisters();
72 inline bool opIn(ExecState
* exec
, JSValue propName
, JSValue baseVal
)
74 if (!baseVal
.isObject()) {
75 exec
->vm().throwException(exec
, createInvalidParameterError(exec
, "in", baseVal
));
79 JSObject
* baseObj
= asObject(baseVal
);
82 if (propName
.getUInt32(i
))
83 return baseObj
->hasProperty(exec
, i
);
86 return baseObj
->hasProperty(exec
, jsCast
<NameInstance
*>(propName
.asCell())->privateName());
88 Identifier
property(exec
, propName
.toString(exec
)->value(exec
));
89 if (exec
->vm().exception())
91 return baseObj
->hasProperty(exec
, property
);
94 } // namespace CommonSlowPaths
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
{
108 inline SlowPathReturnType
encodeResult(void* a
, void* b
)
110 SlowPathReturnType result
;
116 inline void decodeResult(SlowPathReturnType result
, void*& a
, void*& b
)
122 #else // USE(JSVALUE32_64)
123 typedef int64_t SlowPathReturnType
;
131 } SlowPathReturnTypeEncoding
;
133 inline SlowPathReturnType
encodeResult(void* a
, void* b
)
135 SlowPathReturnTypeEncoding u
;
141 inline void decodeResult(SlowPathReturnType result
, void*& a
, void*& b
)
143 SlowPathReturnTypeEncoding u
;
148 #endif // USE(JSVALUE32_64)
152 #define SLOW_PATH_DECL(name) \
153 extern "C" SlowPathReturnType SLOW_PATH name(ExecState* exec, Instruction* pc)
155 #define SLOW_PATH_HIDDEN_DECL(name) \
156 SLOW_PATH_DECL(name) WTF_INTERNAL
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
);
203 #endif // CommonSlowPaths_h