Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / bytecode / BytecodeUseDef.h
1 /*
2  * Copyright (C) 2013-2017 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. 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 #pragma once
27
28 #include "CodeBlock.h"
29
30 namespace JSC {
31
32 template<typename Block, typename Functor, typename Instruction>
33 void computeUsesForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instruction* instruction, const Functor& functor)
34 {
35     if (opcodeID != op_enter && codeBlock->wasCompiledWithDebuggingOpcodes() && codeBlock->scopeRegister().isValid())
36         functor(codeBlock, instruction, opcodeID, codeBlock->scopeRegister().offset());
37
38     switch (opcodeID) {
39     // No uses.
40     case op_new_regexp:
41     case op_new_array_buffer:
42     case op_debug:
43     case op_jneq_ptr:
44     case op_loop_hint:
45     case op_jmp:
46     case op_new_object:
47     case op_enter:
48     case op_argument_count:
49     case op_catch:
50     case op_profile_control_flow:
51     case op_create_direct_arguments:
52     case op_create_cloned_arguments:
53     case op_get_rest_length:
54     case op_check_traps:
55     case op_get_argument:
56     case op_nop:
57     case op_unreachable:
58         return;
59     case op_assert:
60     case op_get_scope:
61     case op_to_this:
62     case op_check_tdz:
63     case op_profile_type:
64     case op_throw:
65     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     case op_log_shadow_chicken_prologue:
74     case op_throw_static_error: {
75         ASSERT(opcodeLengths[opcodeID] > 1);
76         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
77         return;
78     }
79     case op_jlesseq:
80     case op_jgreater:
81     case op_jgreatereq:
82     case op_jnless:
83     case op_jnlesseq:
84     case op_jngreater:
85     case op_jngreatereq:
86     case op_jless:
87     case op_set_function_name:
88     case op_log_shadow_chicken_tail: {
89         ASSERT(opcodeLengths[opcodeID] > 2);
90         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
91         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
92         return;
93     }
94     case op_put_by_val_direct:
95     case op_put_by_val: {
96         ASSERT(opcodeLengths[opcodeID] > 3);
97         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
98         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
99         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
100         return;
101     }
102     case op_put_by_index:
103     case op_put_by_id:
104     case op_put_to_scope:
105     case op_put_to_arguments: {
106         ASSERT(opcodeLengths[opcodeID] > 3);
107         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
108         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
109         return;
110     }
111     case op_put_by_id_with_this: {
112         ASSERT(opcodeLengths[opcodeID] > 4);
113         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
114         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
115         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
116         return;
117     }
118     case op_put_by_val_with_this: {
119         ASSERT(opcodeLengths[opcodeID] > 4);
120         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
121         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
122         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
123         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
124         return;
125     }
126     case op_put_getter_by_id:
127     case op_put_setter_by_id: {
128         ASSERT(opcodeLengths[opcodeID] > 4);
129         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
130         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
131         return;
132     }
133     case op_put_getter_setter_by_id: {
134         ASSERT(opcodeLengths[opcodeID] > 5);
135         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
136         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
137         functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
138         return;
139     }
140     case op_put_getter_by_val:
141     case op_put_setter_by_val: {
142         ASSERT(opcodeLengths[opcodeID] > 4);
143         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
144         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
145         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
146         return;
147     }
148     case op_define_data_property: {
149         ASSERT(opcodeLengths[opcodeID] > 4);
150         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
151         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
152         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
153         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
154         return;
155     }
156     case op_define_accessor_property: {
157         ASSERT(opcodeLengths[opcodeID] > 5);
158         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
159         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
160         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
161         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
162         functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
163         return;
164     }
165     case op_spread:
166     case op_get_property_enumerator:
167     case op_get_enumerable_length:
168     case op_new_func_exp:
169     case op_new_generator_func_exp:
170     case op_new_async_func_exp:
171     case op_to_index_string:
172     case op_create_lexical_environment:
173     case op_resolve_scope:
174     case op_resolve_scope_for_hoisting_func_decl_in_eval:
175     case op_get_from_scope:
176     case op_to_primitive:
177     case op_try_get_by_id:
178     case op_get_by_id:
179     case op_get_by_id_proto_load:
180     case op_get_by_id_unset:
181     case op_get_array_length:
182     case op_typeof:
183     case op_is_empty:
184     case op_is_undefined:
185     case op_is_boolean:
186     case op_is_number:
187     case op_is_object:
188     case op_is_object_or_null:
189     case op_is_cell_with_type:
190     case op_is_function:
191     case op_to_number:
192     case op_to_string:
193     case op_negate:
194     case op_neq_null:
195     case op_eq_null:
196     case op_not:
197     case op_mov:
198     case op_new_array_with_size:
199     case op_create_this:
200     case op_del_by_id:
201     case op_unsigned:
202     case op_new_func:
203     case op_new_generator_func:
204     case op_new_async_func:
205     case op_get_parent_scope:
206     case op_create_scoped_arguments:
207     case op_create_rest:
208     case op_get_from_arguments: {
209         ASSERT(opcodeLengths[opcodeID] > 2);
210         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
211         return;
212     }
213     case op_has_generic_property:
214     case op_has_indexed_property:
215     case op_enumerator_structure_pname:
216     case op_enumerator_generic_pname:
217     case op_get_by_val:
218     case op_in:
219     case op_overrides_has_instance:
220     case op_instanceof:
221     case op_add:
222     case op_mul:
223     case op_div:
224     case op_mod:
225     case op_sub:
226     case op_pow:
227     case op_lshift:
228     case op_rshift:
229     case op_urshift:
230     case op_bitand:
231     case op_bitxor:
232     case op_bitor:
233     case op_less:
234     case op_lesseq:
235     case op_greater:
236     case op_greatereq:
237     case op_nstricteq:
238     case op_stricteq:
239     case op_neq:
240     case op_eq:
241     case op_push_with_scope:
242     case op_get_by_id_with_this:
243     case op_del_by_val:
244     case op_tail_call_forward_arguments: {
245         ASSERT(opcodeLengths[opcodeID] > 3);
246         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
247         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
248         return;
249     }
250     case op_get_by_val_with_this: {
251         ASSERT(opcodeLengths[opcodeID] > 4);
252         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
253         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
254         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
255         return;
256     }
257     case op_instanceof_custom:
258     case op_has_structure_property:
259     case op_construct_varargs:
260     case op_call_varargs:
261     case op_tail_call_varargs: {
262         ASSERT(opcodeLengths[opcodeID] > 4);
263         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
264         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
265         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
266         return;
267     }
268     case op_get_direct_pname: {
269         ASSERT(opcodeLengths[opcodeID] > 5);
270         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
271         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
272         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
273         functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
274         return;
275     }
276     case op_switch_string:
277     case op_switch_char:
278     case op_switch_imm: {
279         ASSERT(opcodeLengths[opcodeID] > 3);
280         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
281         return;
282     }
283     case op_new_array_with_spread:
284     case op_new_array:
285     case op_strcat: {
286         int base = instruction[2].u.operand;
287         int count = instruction[3].u.operand;
288         for (int i = 0; i < count; i++)
289             functor(codeBlock, instruction, opcodeID, base - i);
290         return;
291     }
292     case op_construct:
293     case op_call_eval:
294     case op_call:
295     case op_tail_call: {
296         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
297         int argCount = instruction[3].u.operand;
298         int registerOffset = -instruction[4].u.operand;
299         int lastArg = registerOffset + CallFrame::thisArgumentOffset();
300         for (int i = 0; i < argCount; i++)
301             functor(codeBlock, instruction, opcodeID, lastArg + i);
302         if (opcodeID == op_call_eval)
303             functor(codeBlock, instruction, opcodeID, codeBlock->scopeRegister().offset());
304         return;
305     }
306     case op_yield: {
307         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
308         functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
309         return;
310     }
311     default:
312         RELEASE_ASSERT_NOT_REACHED();
313         break;
314     }
315 }
316
317 template<typename Block, typename Instruction, typename Functor>
318 void computeDefsForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instruction* instruction, const Functor& functor)
319 {
320     switch (opcodeID) {
321     // These don't define anything.
322     case op_put_to_scope:
323     case op_end:
324     case op_throw:
325     case op_throw_static_error:
326     case op_assert:
327     case op_debug:
328     case op_ret:
329     case op_jmp:
330     case op_jtrue:
331     case op_jfalse:
332     case op_jeq_null:
333     case op_jneq_null:
334     case op_jneq_ptr:
335     case op_jless:
336     case op_jlesseq:
337     case op_jgreater:
338     case op_jgreatereq:
339     case op_jnless:
340     case op_jnlesseq:
341     case op_jngreater:
342     case op_jngreatereq:
343     case op_loop_hint:
344     case op_switch_imm:
345     case op_switch_char:
346     case op_switch_string:
347     case op_put_by_id:
348     case op_put_by_id_with_this:
349     case op_put_by_val_with_this:
350     case op_put_getter_by_id:
351     case op_put_setter_by_id:
352     case op_put_getter_setter_by_id:
353     case op_put_getter_by_val:
354     case op_put_setter_by_val:
355     case op_put_by_val:
356     case op_put_by_val_direct:
357     case op_put_by_index:
358     case op_define_data_property:
359     case op_define_accessor_property:
360     case op_profile_type:
361     case op_profile_control_flow:
362     case op_put_to_arguments:
363     case op_set_function_name:
364     case op_check_traps:
365     case op_log_shadow_chicken_prologue:
366     case op_log_shadow_chicken_tail:
367     case op_yield:
368     case op_nop:
369     case op_unreachable:
370 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
371         FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
372 #undef LLINT_HELPER_OPCODES
373         return;
374     // These all have a single destination for the first argument.
375     case op_argument_count:
376     case op_to_index_string:
377     case op_get_enumerable_length:
378     case op_has_indexed_property:
379     case op_has_structure_property:
380     case op_has_generic_property:
381     case op_get_direct_pname:
382     case op_get_property_enumerator:
383     case op_enumerator_structure_pname:
384     case op_enumerator_generic_pname:
385     case op_get_parent_scope:
386     case op_push_with_scope:
387     case op_create_lexical_environment:
388     case op_resolve_scope:
389     case op_resolve_scope_for_hoisting_func_decl_in_eval:
390     case op_strcat:
391     case op_to_primitive:
392     case op_create_this:
393     case op_new_array:
394     case op_new_array_with_spread:
395     case op_spread:
396     case op_new_array_buffer:
397     case op_new_array_with_size:
398     case op_new_regexp:
399     case op_new_func:
400     case op_new_func_exp:
401     case op_new_generator_func:
402     case op_new_generator_func_exp:
403     case op_new_async_func:
404     case op_new_async_func_exp:
405     case op_call_varargs:
406     case op_tail_call_varargs:
407     case op_tail_call_forward_arguments:
408     case op_construct_varargs:
409     case op_get_from_scope:
410     case op_call:
411     case op_tail_call:
412     case op_call_eval:
413     case op_construct:
414     case op_try_get_by_id:
415     case op_get_by_id:
416     case op_get_by_id_proto_load:
417     case op_get_by_id_unset:
418     case op_get_by_id_with_this:
419     case op_get_by_val_with_this:
420     case op_get_array_length:
421     case op_overrides_has_instance:
422     case op_instanceof:
423     case op_instanceof_custom:
424     case op_get_by_val:
425     case op_typeof:
426     case op_is_empty:
427     case op_is_undefined:
428     case op_is_boolean:
429     case op_is_number:
430     case op_is_object:
431     case op_is_object_or_null:
432     case op_is_cell_with_type:
433     case op_is_function:
434     case op_in:
435     case op_to_number:
436     case op_to_string:
437     case op_negate:
438     case op_add:
439     case op_mul:
440     case op_div:
441     case op_mod:
442     case op_sub:
443     case op_pow:
444     case op_lshift:
445     case op_rshift:
446     case op_urshift:
447     case op_bitand:
448     case op_bitxor:
449     case op_bitor:
450     case op_inc:
451     case op_dec:
452     case op_eq:
453     case op_neq:
454     case op_stricteq:
455     case op_nstricteq:
456     case op_less:
457     case op_lesseq:
458     case op_greater:
459     case op_greatereq:
460     case op_neq_null:
461     case op_eq_null:
462     case op_not:
463     case op_mov:
464     case op_new_object:
465     case op_to_this:
466     case op_check_tdz:
467     case op_get_scope:
468     case op_create_direct_arguments:
469     case op_create_scoped_arguments:
470     case op_create_cloned_arguments:
471     case op_del_by_id:
472     case op_del_by_val:
473     case op_unsigned:
474     case op_get_from_arguments: 
475     case op_get_argument:
476     case op_create_rest:
477     case op_get_rest_length: {
478         ASSERT(opcodeLengths[opcodeID] > 1);
479         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
480         return;
481     }
482     case op_catch: {
483         ASSERT(opcodeLengths[opcodeID] > 2);
484         functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
485         functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
486         return;
487     }
488     case op_enter: {
489         for (unsigned i = codeBlock->m_numVars; i--;)
490             functor(codeBlock, instruction, opcodeID, virtualRegisterForLocal(i).offset());
491         return;
492     }
493     }
494 }
495
496 } // namespace JSC