blob: f77a872ba4929b072f9a30eed53b3664b4c96673 [file] [log] [blame]
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00001/*
fpizlo@apple.com718fc672015-03-13 01:57:59 +00002 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
fpizlo@apple.com0309686b2013-12-02 19:49:43 +00003 *
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. 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.
24 */
25
26#ifndef BytecodeUseDef_h
27#define BytecodeUseDef_h
28
29#include "CodeBlock.h"
30
31namespace JSC {
32
33template<typename Functor>
34void computeUsesForBytecodeOffset(
fpizlo@apple.com718fc672015-03-13 01:57:59 +000035 CodeBlock* codeBlock, unsigned bytecodeOffset, const Functor& functor)
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000036{
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);
41 switch (opcodeID) {
42 // No uses.
43 case op_new_regexp:
44 case op_new_array_buffer:
45 case op_throw_static_error:
46 case op_debug:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000047 case op_jneq_ptr:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000048 case op_loop_hint:
49 case op_jmp:
50 case op_new_object:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000051 case op_enter:
52 case op_catch:
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +000053 case op_profile_control_flow:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000054 case op_create_direct_arguments:
55 case op_create_out_of_band_arguments:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000056 return;
msaboff@apple.com8b6b3412014-11-04 03:36:28 +000057 case op_get_scope:
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +000058 case op_load_arrowfunction_this:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000059 case op_to_this:
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +000060 case op_check_tdz:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000061 case op_profile_will_call:
62 case op_profile_did_call:
commit-queue@webkit.org2ed31ec2014-08-21 01:03:20 +000063 case op_profile_type:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000064 case op_throw:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000065 case op_end:
66 case op_ret:
67 case op_jtrue:
68 case op_jfalse:
69 case op_jeq_null:
70 case op_jneq_null:
71 case op_dec:
72 case op_inc: {
73 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
74 return;
75 }
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000076 case op_jlesseq:
77 case op_jgreater:
78 case op_jgreatereq:
79 case op_jnless:
80 case op_jnlesseq:
81 case op_jngreater:
82 case op_jngreatereq:
83 case op_jless: {
84 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
85 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
86 return;
87 }
88 case op_put_by_val_direct:
89 case op_put_by_val: {
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);
93 return;
94 }
95 case op_put_by_index:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000096 case op_put_by_id:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000097 case op_put_to_scope:
98 case op_put_to_arguments: {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +000099 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
100 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
101 return;
102 }
rniwa@webkit.org87ae29c2015-08-14 23:50:25 +0000103 case op_put_getter_by_id:
104 case op_put_setter_by_id: {
105 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
106 functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
107 return;
108 }
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000109 case op_put_getter_setter: {
110 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000111 functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
rniwa@webkit.org87ae29c2015-08-14 23:50:25 +0000112 functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000113 return;
114 }
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000115 case op_put_getter_by_val:
116 case op_put_setter_by_val: {
117 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
118 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
119 functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
120 return;
121 }
msaboff@apple.comb644c252015-03-24 10:05:21 +0000122 case op_get_property_enumerator:
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000123 case op_get_enumerable_length:
msaboff@apple.com5e62e3f2014-11-21 23:41:26 +0000124 case op_new_func_exp:
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +0000125 case op_new_arrow_func_exp:
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000126 case op_to_index_string:
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000127 case op_create_lexical_environment:
msaboff@apple.com5e62e3f2014-11-21 23:41:26 +0000128 case op_resolve_scope:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000129 case op_get_from_scope:
130 case op_to_primitive:
131 case op_get_by_id:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000132 case op_get_array_length:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000133 case op_typeof:
134 case op_is_undefined:
135 case op_is_boolean:
136 case op_is_number:
137 case op_is_string:
138 case op_is_object:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +0000139 case op_is_object_or_null:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000140 case op_is_function:
141 case op_to_number:
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000142 case op_to_string:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000143 case op_negate:
144 case op_neq_null:
145 case op_eq_null:
146 case op_not:
147 case op_mov:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000148 case op_new_array_with_size:
commit-queue@webkit.org19660ce2015-05-12 05:48:57 +0000149 case op_create_this:
fpizlo@apple.com9089acb2013-12-14 06:33:42 +0000150 case op_del_by_id:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000151 case op_unsigned:
152 case op_new_func:
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000153 case op_get_parent_scope:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000154 case op_create_scoped_arguments:
155 case op_get_from_arguments: {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000156 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
157 return;
158 }
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000159 case op_has_generic_property:
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000160 case op_has_indexed_property:
msaboff@apple.comb644c252015-03-24 10:05:21 +0000161 case op_enumerator_structure_pname:
162 case op_enumerator_generic_pname:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000163 case op_get_by_val:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000164 case op_in:
165 case op_instanceof:
166 case op_check_has_instance:
167 case op_add:
168 case op_mul:
169 case op_div:
170 case op_mod:
171 case op_sub:
172 case op_lshift:
173 case op_rshift:
174 case op_urshift:
175 case op_bitand:
176 case op_bitxor:
177 case op_bitor:
178 case op_less:
179 case op_lesseq:
180 case op_greater:
181 case op_greatereq:
182 case op_nstricteq:
183 case op_stricteq:
184 case op_neq:
185 case op_eq:
saambarati1@gmail.come85426c2015-08-07 17:41:22 +0000186 case op_push_with_scope:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000187 case op_del_by_val: {
188 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
189 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
190 return;
191 }
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000192 case op_has_structure_property:
oliver@apple.com177c2b92014-03-28 01:10:25 +0000193 case op_construct_varargs:
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000194 case op_call_varargs:
195 case op_tail_call_varargs: {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000196 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
197 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
198 functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
199 return;
200 }
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000201 case op_get_direct_pname: {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000202 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
203 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
204 functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
205 functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
206 return;
207 }
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000208 case op_switch_string:
209 case op_switch_char:
210 case op_switch_imm: {
211 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
212 return;
213 }
214 case op_new_array:
215 case op_strcat: {
216 int base = instruction[2].u.operand;
217 int count = instruction[3].u.operand;
218 for (int i = 0; i < count; i++)
219 functor(codeBlock, instruction, opcodeID, base - i);
220 return;
221 }
222 case op_construct:
223 case op_call_eval:
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000224 case op_call:
225 case op_tail_call: {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000226 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
227 int argCount = instruction[3].u.operand;
228 int registerOffset = -instruction[4].u.operand;
229 int lastArg = registerOffset + CallFrame::thisArgumentOffset();
rniwa@webkit.orgfda6b5e2015-02-25 00:41:35 +0000230 for (int i = 0; i < argCount; i++)
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000231 functor(codeBlock, instruction, opcodeID, lastArg + i);
232 return;
233 }
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000234 default:
235 RELEASE_ASSERT_NOT_REACHED();
236 break;
237 }
238}
239
240template<typename Functor>
fpizlo@apple.com718fc672015-03-13 01:57:59 +0000241void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, const Functor& functor)
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000242{
243 Interpreter* interpreter = codeBlock->vm()->interpreter;
244 Instruction* instructionsBegin = codeBlock->instructions().begin();
245 Instruction* instruction = &instructionsBegin[bytecodeOffset];
246 OpcodeID opcodeID = interpreter->getOpcodeID(instruction->u.opcode);
247 switch (opcodeID) {
248 // These don't define anything.
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000249 case op_put_to_scope:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000250 case op_end:
251 case op_profile_will_call:
252 case op_profile_did_call:
253 case op_throw:
254 case op_throw_static_error:
255 case op_debug:
256 case op_ret:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000257 case op_jmp:
258 case op_jtrue:
259 case op_jfalse:
260 case op_jeq_null:
261 case op_jneq_null:
262 case op_jneq_ptr:
263 case op_jless:
264 case op_jlesseq:
265 case op_jgreater:
266 case op_jgreatereq:
267 case op_jnless:
268 case op_jnlesseq:
269 case op_jngreater:
270 case op_jngreatereq:
271 case op_loop_hint:
272 case op_switch_imm:
273 case op_switch_char:
274 case op_switch_string:
275 case op_put_by_id:
commit-queue@webkit.orgfb471b42015-05-14 01:32:25 +0000276 case op_put_getter_by_id:
277 case op_put_setter_by_id:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000278 case op_put_getter_setter:
utatane.tea@gmail.comf0153d02015-09-08 19:43:58 +0000279 case op_put_getter_by_val:
280 case op_put_setter_by_val:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000281 case op_put_by_val:
282 case op_put_by_val_direct:
283 case op_put_by_index:
commit-queue@webkit.org2ed31ec2014-08-21 01:03:20 +0000284 case op_profile_type:
saambarati1@gmail.comb4f28a52014-12-05 05:58:07 +0000285 case op_profile_control_flow:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000286 case op_put_to_arguments:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000287#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
288 FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
289#undef LLINT_HELPER_OPCODES
290 return;
291 // These all have a single destination for the first argument.
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000292 case op_to_index_string:
fpizlo@apple.coma398a562014-08-06 21:32:55 +0000293 case op_get_enumerable_length:
294 case op_has_indexed_property:
295 case op_has_structure_property:
296 case op_has_generic_property:
297 case op_get_direct_pname:
msaboff@apple.comb644c252015-03-24 10:05:21 +0000298 case op_get_property_enumerator:
299 case op_enumerator_structure_pname:
300 case op_enumerator_generic_pname:
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000301 case op_get_parent_scope:
msaboff@apple.com5e62e3f2014-11-21 23:41:26 +0000302 case op_push_with_scope:
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000303 case op_create_lexical_environment:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000304 case op_resolve_scope:
305 case op_strcat:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000306 case op_to_primitive:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000307 case op_create_this:
308 case op_new_array:
309 case op_new_array_buffer:
310 case op_new_array_with_size:
311 case op_new_regexp:
312 case op_new_func:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000313 case op_new_func_exp:
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +0000314 case op_new_arrow_func_exp:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000315 case op_call_varargs:
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000316 case op_tail_call_varargs:
oliver@apple.com177c2b92014-03-28 01:10:25 +0000317 case op_construct_varargs:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000318 case op_get_from_scope:
319 case op_call:
msaboff@apple.comc15ae7e2015-09-16 23:40:35 +0000320 case op_tail_call:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000321 case op_call_eval:
322 case op_construct:
323 case op_get_by_id:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000324 case op_get_array_length:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000325 case op_check_has_instance:
326 case op_instanceof:
327 case op_get_by_val:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000328 case op_typeof:
329 case op_is_undefined:
330 case op_is_boolean:
331 case op_is_number:
332 case op_is_string:
333 case op_is_object:
utatane.tea@gmail.com0bfb74c2015-02-24 23:01:58 +0000334 case op_is_object_or_null:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000335 case op_is_function:
336 case op_in:
337 case op_to_number:
utatane.tea@gmail.com4014aea2015-04-27 00:27:28 +0000338 case op_to_string:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000339 case op_negate:
340 case op_add:
341 case op_mul:
342 case op_div:
343 case op_mod:
344 case op_sub:
345 case op_lshift:
346 case op_rshift:
347 case op_urshift:
348 case op_bitand:
349 case op_bitxor:
350 case op_bitor:
351 case op_inc:
352 case op_dec:
353 case op_eq:
354 case op_neq:
355 case op_stricteq:
356 case op_nstricteq:
357 case op_less:
358 case op_lesseq:
359 case op_greater:
360 case op_greatereq:
361 case op_neq_null:
362 case op_eq_null:
363 case op_not:
364 case op_mov:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000365 case op_new_object:
366 case op_to_this:
rniwa@webkit.orgeb7ac192015-03-13 01:11:15 +0000367 case op_check_tdz:
msaboff@apple.com8b6b3412014-11-04 03:36:28 +0000368 case op_get_scope:
commit-queue@webkit.orga4201b02015-08-17 22:24:20 +0000369 case op_load_arrowfunction_this:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000370 case op_create_direct_arguments:
371 case op_create_scoped_arguments:
372 case op_create_out_of_band_arguments:
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000373 case op_del_by_id:
fpizlo@apple.com9089acb2013-12-14 06:33:42 +0000374 case op_del_by_val:
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000375 case op_unsigned:
376 case op_get_from_arguments: {
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000377 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
378 return;
379 }
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000380 case op_catch: {
msaboff@apple.com5e62e3f2014-11-21 23:41:26 +0000381 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
382 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
383 return;
384 }
fpizlo@apple.com0309686b2013-12-02 19:49:43 +0000385 case op_enter: {
386 for (unsigned i = codeBlock->m_numVars; i--;)
387 functor(codeBlock, instruction, opcodeID, virtualRegisterForLocal(i).offset());
388 return;
389 } }
390}
391
392} // namespace JSC
393
394#endif // BytecodeUseDef_h
395