2 * Copyright (C) 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. 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
, 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
:
47 case op_resolve_scope
:
54 case op_init_lazy_reg
:
61 case op_new_captured_func
:
62 case op_create_activation
:
63 case op_create_arguments
:
65 case op_tear_off_activation
:
66 case op_profile_will_call
:
67 case op_profile_did_call
:
69 case op_push_with_scope
:
78 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
81 case op_ret_object_or_this
:
90 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
91 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
94 case op_put_by_val_direct
:
96 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
97 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
98 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
101 case op_put_by_index
:
102 case op_put_by_id_transition_direct
:
103 case op_put_by_id_transition_direct_out_of_line
:
104 case op_put_by_id_transition_normal
:
105 case op_put_by_id_transition_normal_out_of_line
:
106 case op_put_by_id_out_of_line
:
108 case op_put_to_scope
: {
109 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
110 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
113 case op_put_getter_setter
: {
114 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
115 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
116 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
119 case op_init_global_const_nop
:
120 case op_init_global_const
:
121 case op_push_name_scope
:
122 case op_get_from_scope
:
123 case op_to_primitive
:
125 case op_get_by_id_out_of_line
:
126 case op_get_array_length
:
127 case op_get_arguments_length
:
129 case op_is_undefined
:
141 case op_captured_mov
:
142 case op_new_array_with_size
:
147 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
151 case op_get_argument_by_val
:
154 case op_check_has_instance
:
174 case op_del_by_val
: {
175 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
176 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
179 case op_construct_varargs
:
180 case op_call_varargs
: {
181 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
182 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
183 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
186 case op_next_pname
: {
187 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
188 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
189 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
190 functor(codeBlock
, instruction
, opcodeID
, instruction
[5].u
.operand
);
193 case op_get_by_pname
: {
194 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
195 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
196 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
197 functor(codeBlock
, instruction
, opcodeID
, instruction
[5].u
.operand
);
198 functor(codeBlock
, instruction
, opcodeID
, instruction
[6].u
.operand
);
201 case op_switch_string
:
203 case op_switch_imm
: {
204 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
209 int base
= instruction
[2].u
.operand
;
210 int count
= instruction
[3].u
.operand
;
211 for (int i
= 0; i
< count
; i
++)
212 functor(codeBlock
, instruction
, opcodeID
, base
- i
);
218 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
219 int argCount
= instruction
[3].u
.operand
;
220 int registerOffset
= -instruction
[4].u
.operand
;
221 int lastArg
= registerOffset
+ CallFrame::thisArgumentOffset();
222 for (int i
= opcodeID
== op_construct
? 1 : 0; i
< argCount
; i
++)
223 functor(codeBlock
, instruction
, opcodeID
, lastArg
+ i
);
226 case op_tear_off_arguments
: {
227 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
228 functor(codeBlock
, instruction
, opcodeID
, unmodifiedArgumentsRegister(VirtualRegister(instruction
[1].u
.operand
)).offset());
229 functor(codeBlock
, instruction
, opcodeID
, instruction
[2].u
.operand
);
233 RELEASE_ASSERT_NOT_REACHED();
238 template<typename Functor
>
239 void computeDefsForBytecodeOffset(CodeBlock
* codeBlock
, unsigned bytecodeOffset
, Functor
& functor
)
241 Interpreter
* interpreter
= codeBlock
->vm()->interpreter
;
242 Instruction
* instructionsBegin
= codeBlock
->instructions().begin();
243 Instruction
* instruction
= &instructionsBegin
[bytecodeOffset
];
244 OpcodeID opcodeID
= interpreter
->getOpcodeID(instruction
->u
.opcode
);
246 // These don't define anything.
247 case op_init_global_const
:
248 case op_init_global_const_nop
:
249 case op_push_name_scope
:
250 case op_push_with_scope
:
251 case op_put_to_scope
:
254 case op_profile_will_call
:
255 case op_profile_did_call
:
257 case op_throw_static_error
:
260 case op_ret_object_or_this
:
278 case op_switch_string
:
280 case op_put_by_id_out_of_line
:
281 case op_put_by_id_transition_direct
:
282 case op_put_by_id_transition_direct_out_of_line
:
283 case op_put_by_id_transition_normal
:
284 case op_put_by_id_transition_normal_out_of_line
:
285 case op_put_getter_setter
:
287 case op_put_by_val_direct
:
288 case op_put_by_index
:
289 case op_tear_off_arguments
:
291 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
292 FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES
);
293 #undef LLINT_HELPER_OPCODES
295 // These all have a single destination for the first argument.
297 case op_resolve_scope
:
299 case op_tear_off_activation
:
300 case op_to_primitive
:
304 case op_new_array_buffer
:
305 case op_new_array_with_size
:
308 case op_new_captured_func
:
309 case op_new_func_exp
:
310 case op_call_varargs
:
311 case op_construct_varargs
:
312 case op_get_from_scope
:
317 case op_get_by_id_out_of_line
:
318 case op_get_array_length
:
319 case op_check_has_instance
:
322 case op_get_argument_by_val
:
323 case op_get_by_pname
:
324 case op_get_arguments_length
:
326 case op_is_undefined
:
360 case op_captured_mov
:
364 case op_init_lazy_reg
:
365 case op_create_activation
:
366 case op_create_arguments
:
370 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
373 case op_get_pnames
: {
374 functor(codeBlock
, instruction
, opcodeID
, instruction
[1].u
.operand
);
375 functor(codeBlock
, instruction
, opcodeID
, instruction
[3].u
.operand
);
376 functor(codeBlock
, instruction
, opcodeID
, instruction
[4].u
.operand
);
380 for (unsigned i
= codeBlock
->m_numVars
; i
--;)
381 functor(codeBlock
, instruction
, opcodeID
, virtualRegisterForLocal(i
).offset());
388 #endif // BytecodeUseDef_h