]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/BytecodeUseDef.h
JavaScriptCore-7600.1.4.17.5.tar.gz
[apple/javascriptcore.git] / bytecode / BytecodeUseDef.h
1 /*
2 * Copyright (C) 2013 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 #ifndef BytecodeUseDef_h
27 #define BytecodeUseDef_h
28
29 #include "CodeBlock.h"
30
31 namespace JSC {
32
33 template<typename Functor>
34 void computeUsesForBytecodeOffset(
35 CodeBlock* codeBlock, unsigned bytecodeOffset, Functor& functor)
36 {
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:
47 case op_resolve_scope:
48 case op_pop_scope:
49 case op_jneq_ptr:
50 case op_new_func_exp:
51 case op_loop_hint:
52 case op_jmp:
53 case op_new_object:
54 case op_init_lazy_reg:
55 case op_get_callee:
56 case op_enter:
57 case op_catch:
58 case op_touch_entry:
59 return;
60 case op_new_func:
61 case op_new_captured_func:
62 case op_create_activation:
63 case op_create_arguments:
64 case op_to_this:
65 case op_tear_off_activation:
66 case op_profile_will_call:
67 case op_profile_did_call:
68 case op_throw:
69 case op_push_with_scope:
70 case op_end:
71 case op_ret:
72 case op_jtrue:
73 case op_jfalse:
74 case op_jeq_null:
75 case op_jneq_null:
76 case op_dec:
77 case op_inc: {
78 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
79 return;
80 }
81 case op_ret_object_or_this:
82 case op_jlesseq:
83 case op_jgreater:
84 case op_jgreatereq:
85 case op_jnless:
86 case op_jnlesseq:
87 case op_jngreater:
88 case op_jngreatereq:
89 case op_jless: {
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 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);
99 return;
100 }
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:
107 case op_put_by_id:
108 case op_put_to_scope: {
109 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
110 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
111 return;
112 }
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);
117 return;
118 }
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:
124 case op_get_by_id:
125 case op_get_by_id_out_of_line:
126 case op_get_array_length:
127 case op_get_arguments_length:
128 case op_typeof:
129 case op_is_undefined:
130 case op_is_boolean:
131 case op_is_number:
132 case op_is_string:
133 case op_is_object:
134 case op_is_function:
135 case op_to_number:
136 case op_negate:
137 case op_neq_null:
138 case op_eq_null:
139 case op_not:
140 case op_mov:
141 case op_captured_mov:
142 case op_new_array_with_size:
143 case op_create_this:
144 case op_get_pnames:
145 case op_del_by_id:
146 case op_unsigned: {
147 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
148 return;
149 }
150 case op_get_by_val:
151 case op_get_argument_by_val:
152 case op_in:
153 case op_instanceof:
154 case op_check_has_instance:
155 case op_add:
156 case op_mul:
157 case op_div:
158 case op_mod:
159 case op_sub:
160 case op_lshift:
161 case op_rshift:
162 case op_urshift:
163 case op_bitand:
164 case op_bitxor:
165 case op_bitor:
166 case op_less:
167 case op_lesseq:
168 case op_greater:
169 case op_greatereq:
170 case op_nstricteq:
171 case op_stricteq:
172 case op_neq:
173 case op_eq:
174 case op_del_by_val: {
175 functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
176 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
177 return;
178 }
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);
184 return;
185 }
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);
191 return;
192 }
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);
199 return;
200 }
201 case op_switch_string:
202 case op_switch_char:
203 case op_switch_imm: {
204 functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
205 return;
206 }
207 case op_new_array:
208 case op_strcat: {
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);
213 return;
214 }
215 case op_construct:
216 case op_call_eval:
217 case op_call: {
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);
224 return;
225 }
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);
230 return;
231 }
232 default:
233 RELEASE_ASSERT_NOT_REACHED();
234 break;
235 }
236 }
237
238 template<typename Functor>
239 void computeDefsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, Functor& functor)
240 {
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);
245 switch (opcodeID) {
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:
252 case op_pop_scope:
253 case op_end:
254 case op_profile_will_call:
255 case op_profile_did_call:
256 case op_throw:
257 case op_throw_static_error:
258 case op_debug:
259 case op_ret:
260 case op_ret_object_or_this:
261 case op_jmp:
262 case op_jtrue:
263 case op_jfalse:
264 case op_jeq_null:
265 case op_jneq_null:
266 case op_jneq_ptr:
267 case op_jless:
268 case op_jlesseq:
269 case op_jgreater:
270 case op_jgreatereq:
271 case op_jnless:
272 case op_jnlesseq:
273 case op_jngreater:
274 case op_jngreatereq:
275 case op_loop_hint:
276 case op_switch_imm:
277 case op_switch_char:
278 case op_switch_string:
279 case op_put_by_id:
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:
286 case op_put_by_val:
287 case op_put_by_val_direct:
288 case op_put_by_index:
289 case op_tear_off_arguments:
290 case op_touch_entry:
291 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
292 FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
293 #undef LLINT_HELPER_OPCODES
294 return;
295 // These all have a single destination for the first argument.
296 case op_next_pname:
297 case op_resolve_scope:
298 case op_strcat:
299 case op_tear_off_activation:
300 case op_to_primitive:
301 case op_catch:
302 case op_create_this:
303 case op_new_array:
304 case op_new_array_buffer:
305 case op_new_array_with_size:
306 case op_new_regexp:
307 case op_new_func:
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:
313 case op_call:
314 case op_call_eval:
315 case op_construct:
316 case op_get_by_id:
317 case op_get_by_id_out_of_line:
318 case op_get_array_length:
319 case op_check_has_instance:
320 case op_instanceof:
321 case op_get_by_val:
322 case op_get_argument_by_val:
323 case op_get_by_pname:
324 case op_get_arguments_length:
325 case op_typeof:
326 case op_is_undefined:
327 case op_is_boolean:
328 case op_is_number:
329 case op_is_string:
330 case op_is_object:
331 case op_is_function:
332 case op_in:
333 case op_to_number:
334 case op_negate:
335 case op_add:
336 case op_mul:
337 case op_div:
338 case op_mod:
339 case op_sub:
340 case op_lshift:
341 case op_rshift:
342 case op_urshift:
343 case op_bitand:
344 case op_bitxor:
345 case op_bitor:
346 case op_inc:
347 case op_dec:
348 case op_eq:
349 case op_neq:
350 case op_stricteq:
351 case op_nstricteq:
352 case op_less:
353 case op_lesseq:
354 case op_greater:
355 case op_greatereq:
356 case op_neq_null:
357 case op_eq_null:
358 case op_not:
359 case op_mov:
360 case op_captured_mov:
361 case op_new_object:
362 case op_to_this:
363 case op_get_callee:
364 case op_init_lazy_reg:
365 case op_create_activation:
366 case op_create_arguments:
367 case op_del_by_id:
368 case op_del_by_val:
369 case op_unsigned: {
370 functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
371 return;
372 }
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);
377 return;
378 }
379 case op_enter: {
380 for (unsigned i = codeBlock->m_numVars; i--;)
381 functor(codeBlock, instruction, opcodeID, virtualRegisterForLocal(i).offset());
382 return;
383 } }
384 }
385
386 } // namespace JSC
387
388 #endif // BytecodeUseDef_h
389