2 * Copyright (C) 2013, 2015 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef BytecodeUseDef_h
27 #define BytecodeUseDef_h
29 #include "CodeBlock.h"
33 template<typename Functor
>
34 void computeUsesForBytecodeOffset(
35 CodeBlock
* codeBlock
, unsigned bytecodeOffset
, const Functor
& functor
)
37 Interpreter
* interpreter
= codeBlock
->vm()->interpreter
;
38 Instruction
* instructionsBegin
= codeBlock
->instructions().begin();
39 Instruction
* instruction
= &instructionsBegin
[bytecodeOffset
];
40 OpcodeID opcodeID
= interpreter
->getOpcodeID(instruction
->u
.opcode
);
44 case op_new_array_buffer
:
45 case op_throw_static_error
:
53 case op_profile_control_flow
:
54 case op_create_direct_arguments
:
55 case op_create_out_of_band_arguments
:
61 case op_profile_will_call
:
62 case op_profile_did_call
:
73 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
84 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
85 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
88 case op_put_by_val_direct
:
90 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
91 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
92 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
96 case op_put_by_id_transition_direct
:
97 case op_put_by_id_transition_direct_out_of_line
:
98 case op_put_by_id_transition_normal
:
99 case op_put_by_id_transition_normal_out_of_line
:
100 case op_put_by_id_out_of_line
:
102 case op_put_getter_by_id
:
103 case op_put_setter_by_id
:
104 case op_put_to_scope
:
105 case op_put_to_arguments
: {
106 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
107 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
110 case op_put_getter_setter
: {
111 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
112 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
113 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
116 case op_create_lexical_environment
:
117 case op_get_property_enumerator
:
118 case op_get_enumerable_length
:
119 case op_new_func_exp
:
120 case op_to_index_string
:
121 case op_init_global_const_nop
:
122 case op_init_global_const
:
123 case op_push_name_scope
:
124 case op_push_with_scope
:
125 case op_resolve_scope
:
126 case op_get_from_scope
:
127 case op_to_primitive
:
129 case op_get_by_id_out_of_line
:
130 case op_get_array_length
:
132 case op_is_undefined
:
137 case op_is_object_or_null
:
146 case op_new_array_with_size
:
151 case op_create_scoped_arguments
:
152 case op_get_from_arguments
: {
153 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
156 case op_has_generic_property
:
157 case op_has_indexed_property
:
158 case op_enumerator_structure_pname
:
159 case op_enumerator_generic_pname
:
163 case op_check_has_instance
:
183 case op_del_by_val
: {
184 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
185 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
188 case op_has_structure_property
:
189 case op_construct_varargs
:
190 case op_call_varargs
: {
191 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
192 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
193 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
196 case op_get_direct_pname
: {
197 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
198 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
199 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
200 functor(codeBlock
, instruction
, opcodeID
, instruction
[5].u
.operand
);
203 case op_switch_string
:
205 case op_switch_imm
: {
206 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
211 int base
= instruction
[2].u
.operand
;
212 int count
= instruction
[3].u
.operand
;
213 for (int i
= 0; i
< count
; i
++)
214 functor(codeBlock
, instruction
, opcodeID
, base
- i
);
220 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
221 int argCount
= instruction
[3].u
.operand
;
222 int registerOffset
= -instruction
[4].u
.operand
;
223 int lastArg
= registerOffset
+ CallFrame::thisArgumentOffset();
224 for (int i
= 0; i
< argCount
; i
++)
225 functor(codeBlock
, instruction
, opcodeID
, lastArg
+ i
);
229 RELEASE_ASSERT_NOT_REACHED();
234 template<typename Functor
>
235 void computeDefsForBytecodeOffset(CodeBlock
* codeBlock
, unsigned bytecodeOffset
, const Functor
& functor
)
237 Interpreter
* interpreter
= codeBlock
->vm()->interpreter
;
238 Instruction
* instructionsBegin
= codeBlock
->instructions().begin();
239 Instruction
* instruction
= &instructionsBegin
[bytecodeOffset
];
240 OpcodeID opcodeID
= interpreter
->getOpcodeID(instruction
->u
.opcode
);
242 // These don't define anything.
243 case op_init_global_const
:
244 case op_init_global_const_nop
:
245 case op_put_to_scope
:
247 case op_profile_will_call
:
248 case op_profile_did_call
:
250 case op_throw_static_error
:
270 case op_switch_string
:
272 case op_put_by_id_out_of_line
:
273 case op_put_by_id_transition_direct
:
274 case op_put_by_id_transition_direct_out_of_line
:
275 case op_put_by_id_transition_normal
:
276 case op_put_by_id_transition_normal_out_of_line
:
277 case op_put_getter_by_id
:
278 case op_put_setter_by_id
:
279 case op_put_getter_setter
:
281 case op_put_by_val_direct
:
282 case op_put_by_index
:
283 case op_profile_type
:
284 case op_profile_control_flow
:
285 case op_put_to_arguments
:
286 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
287 FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES
);
288 #undef LLINT_HELPER_OPCODES
290 // These all have a single destination for the first argument.
291 case op_to_index_string
:
292 case op_get_enumerable_length
:
293 case op_has_indexed_property
:
294 case op_has_structure_property
:
295 case op_has_generic_property
:
296 case op_get_direct_pname
:
297 case op_get_property_enumerator
:
298 case op_enumerator_structure_pname
:
299 case op_enumerator_generic_pname
:
301 case op_push_name_scope
:
302 case op_push_with_scope
:
303 case op_resolve_scope
:
305 case op_to_primitive
:
308 case op_new_array_buffer
:
309 case op_new_array_with_size
:
312 case op_new_func_exp
:
313 case op_call_varargs
:
314 case op_construct_varargs
:
315 case op_get_from_scope
:
320 case op_get_by_id_out_of_line
:
321 case op_get_array_length
:
322 case op_check_has_instance
:
326 case op_is_undefined
:
331 case op_is_object_or_null
:
366 case op_create_direct_arguments
:
367 case op_create_scoped_arguments
:
368 case op_create_out_of_band_arguments
:
372 case op_get_from_arguments
: {
373 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
377 case op_create_lexical_environment
: {
378 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
379 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
383 for (unsigned i
= codeBlock
->m_numVars
; i
--;)
384 functor(codeBlock
, instruction
, opcodeID
, virtualRegisterForLocal(i
).offset());
391 #endif // BytecodeUseDef_h