1/*
2 * Copyright (C) 2013-2019 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 "BytecodeStructs.h"
29#include "CodeBlock.h"
30#include "Instruction.h"
31#include <wtf/Forward.h>
32
33namespace JSC {
34
35#define CALL_FUNCTOR(__arg) \
36 functor(__bytecode.m_##__arg);
37
38#define USES_OR_DEFS(__opcode, ...) \
39 case __opcode::opcodeID: { \
40 auto __bytecode = instruction->as<__opcode>(); \
41 WTF_LAZY_FOR_EACH_TERM(CALL_FUNCTOR, __VA_ARGS__) \
42 return; \
43 }
44
45#define USES USES_OR_DEFS
46#define DEFS USES_OR_DEFS
47
48template<typename Block, typename Functor>
49void computeUsesForBytecodeIndex(Block* codeBlock, OpcodeID opcodeID, const Instruction* instruction, const Functor& functor)
50{
51 if (opcodeID != op_enter && (codeBlock->wasCompiledWithDebuggingOpcodes() || codeBlock->usesEval()) && codeBlock->scopeRegister().isValid())
52 functor(codeBlock->scopeRegister());
53
54 auto handleNewArrayLike = [&](auto op) {
55 int base = op.m_argv.offset();
56 for (int i = 0; i < static_cast<int>(op.m_argc); i++)
57 functor(VirtualRegister { base - i });
58 };
59
60 auto handleOpCallLike = [&](auto op) {
61 functor(op.m_callee);
62 int lastArg = -static_cast<int>(op.m_argv) + CallFrame::thisArgumentOffset();
63 for (int i = 0; i < static_cast<int>(op.m_argc); i++)
64 functor(VirtualRegister { lastArg + i });
65 if (opcodeID == op_call_eval)
66 functor(codeBlock->scopeRegister());
67 return;
68 };
69
70 switch (opcodeID) {
71 case op_wide16:
72 case op_wide32:
73 RELEASE_ASSERT_NOT_REACHED();
74
75 // No uses.
76 case op_new_regexp:
77 case op_debug:
78 case op_jneq_ptr:
79 case op_loop_hint:
80 case op_jmp:
81 case op_new_object:
82 case op_new_promise:
83 case op_new_generator:
84 case op_enter:
85 case op_argument_count:
86 case op_catch:
87 case op_profile_control_flow:
88 case op_create_direct_arguments:
89 case op_create_cloned_arguments:
90 case op_get_rest_length:
91 case op_check_traps:
92 case op_get_argument:
93 case op_nop:
94 case op_unreachable:
95 case op_super_sampler_begin:
96 case op_super_sampler_end:
97 return;
98
99 USES(OpGetScope, dst)
100 USES(OpToThis, srcDst)
101 USES(OpCheckTdz, targetVirtualRegister)
102 USES(OpIdentityWithProfile, srcDst)
103 USES(OpProfileType, targetVirtualRegister);
104 USES(OpThrow, value)
105 USES(OpThrowStaticError, message)
106 USES(OpEnd, value)
107 USES(OpRet, value)
108 USES(OpJtrue, condition)
109 USES(OpJfalse, condition)
110 USES(OpJeqNull, value)
111 USES(OpJneqNull, value)
112 USES(OpJundefinedOrNull, value)
113 USES(OpJnundefinedOrNull, value)
114 USES(OpDec, srcDst)
115 USES(OpInc, srcDst)
116 USES(OpLogShadowChickenPrologue, scope)
117
118 USES(OpJless, lhs, rhs)
119 USES(OpJlesseq, lhs, rhs)
120 USES(OpJgreater, lhs, rhs)
121 USES(OpJgreatereq, lhs, rhs)
122 USES(OpJnless, lhs, rhs)
123 USES(OpJnlesseq, lhs, rhs)
124 USES(OpJngreater, lhs, rhs)
125 USES(OpJngreatereq, lhs, rhs)
126 USES(OpJeq, lhs, rhs)
127 USES(OpJneq, lhs, rhs)
128 USES(OpJstricteq, lhs, rhs)
129 USES(OpJnstricteq, lhs, rhs)
130 USES(OpJbelow, lhs, rhs)
131 USES(OpJbeloweq, lhs, rhs)
132 USES(OpSetFunctionName, function, name)
133 USES(OpLogShadowChickenTail, thisValue, scope)
134
135 USES(OpPutByVal, base, property, value)
136 USES(OpPutByValDirect, base, property, value)
137
138 USES(OpPutById, base, value)
139 USES(OpPutToScope, scope, value)
140 USES(OpPutToArguments, arguments, value)
141
142 USES(OpPutByIdWithThis, base, thisValue, value)
143
144 USES(OpPutByValWithThis, base, thisValue, property, value)
145
146 USES(OpPutGetterById, base, accessor)
147 USES(OpPutSetterById, base, accessor)
148
149 USES(OpPutGetterSetterById, base, getter, setter)
150
151 USES(OpPutGetterByVal, base, property, accessor)
152 USES(OpPutSetterByVal, base, property, accessor)
153
154 USES(OpDefineDataProperty, base, property, value, attributes)
155
156 USES(OpDefineAccessorProperty, base, property, getter, setter, attributes)
157
158 USES(OpSpread, argument)
159 USES(OpGetPropertyEnumerator, base)
160 USES(OpGetEnumerableLength, base)
161 USES(OpNewFuncExp, scope)
162 USES(OpNewGeneratorFuncExp, scope)
163 USES(OpNewAsyncFuncExp, scope)
164 USES(OpToIndexString, index)
165 USES(OpCreateLexicalEnvironment, scope, symbolTable, initialValue)
166 USES(OpCreateGeneratorFrameEnvironment, scope, symbolTable, initialValue)
167 USES(OpResolveScope, scope)
168 USES(OpResolveScopeForHoistingFuncDeclInEval, scope)
169 USES(OpGetFromScope, scope)
170 USES(OpToPrimitive, src)
171 USES(OpTryGetById, base)
172 USES(OpGetById, base)
173 USES(OpGetByIdDirect, base)
174 USES(OpInById, base)
175 USES(OpTypeof, value)
176 USES(OpIsEmpty, operand)
177 USES(OpIsUndefined, operand)
178 USES(OpIsUndefinedOrNull, operand)
179 USES(OpIsBoolean, operand)
180 USES(OpIsNumber, operand)
181 USES(OpIsObject, operand)
182 USES(OpIsObjectOrNull, operand)
183 USES(OpIsCellWithType, operand)
184 USES(OpIsFunction, operand)
185 USES(OpToNumber, operand)
186 USES(OpToNumeric, operand)
187 USES(OpToString, operand)
188 USES(OpToObject, operand)
189 USES(OpNegate, operand)
190 USES(OpBitnot, operand)
191 USES(OpEqNull, operand)
192 USES(OpNeqNull, operand)
193 USES(OpNot, operand)
194 USES(OpUnsigned, operand)
195 USES(OpMov, src)
196 USES(OpNewArrayWithSize, length)
197 USES(OpCreateThis, callee)
198 USES(OpCreatePromise, callee)
199 USES(OpCreateGenerator, callee)
200 USES(OpCreateAsyncGenerator, callee)
201 USES(OpDelById, base)
202 USES(OpNewFunc, scope)
203 USES(OpNewAsyncGeneratorFunc, scope)
204 USES(OpNewAsyncGeneratorFuncExp, scope)
205 USES(OpNewGeneratorFunc, scope)
206 USES(OpNewAsyncFunc, scope)
207 USES(OpGetParentScope, scope)
208 USES(OpCreateScopedArguments, scope)
209 USES(OpCreateRest, arraySize)
210 USES(OpGetFromArguments, arguments)
211 USES(OpNewArrayBuffer, immutableButterfly)
212
213 USES(OpHasGenericProperty, base, property)
214 USES(OpHasIndexedProperty, base, property)
215 USES(OpEnumeratorStructurePname, enumerator, index)
216 USES(OpEnumeratorGenericPname, enumerator, index)
217 USES(OpGetByVal, base, property)
218 USES(OpInByVal, base, property)
219 USES(OpOverridesHasInstance, constructor, hasInstanceValue)
220 USES(OpInstanceof, value, prototype)
221 USES(OpAdd, lhs, rhs)
222 USES(OpMul, lhs, rhs)
223 USES(OpDiv, lhs, rhs)
224 USES(OpMod, lhs, rhs)
225 USES(OpSub, lhs, rhs)
226 USES(OpPow, lhs, rhs)
227 USES(OpLshift, lhs, rhs)
228 USES(OpRshift, lhs, rhs)
229 USES(OpUrshift, lhs, rhs)
230 USES(OpBitand, lhs, rhs)
231 USES(OpBitxor, lhs, rhs)
232 USES(OpBitor, lhs, rhs)
233 USES(OpLess, lhs, rhs)
234 USES(OpLesseq, lhs, rhs)
235 USES(OpGreater, lhs, rhs)
236 USES(OpGreatereq, lhs, rhs)
237 USES(OpBelow, lhs, rhs)
238 USES(OpBeloweq, lhs, rhs)
239 USES(OpNstricteq, lhs, rhs)
240 USES(OpStricteq, lhs, rhs)
241 USES(OpNeq, lhs, rhs)
242 USES(OpEq, lhs, rhs)
243 USES(OpPushWithScope, currentScope, newScope)
244 USES(OpGetByIdWithThis, base, thisValue)
245 USES(OpDelByVal, base, property)
246 USES(OpTailCallForwardArguments, callee, thisValue)
247
248 USES(OpGetByValWithThis, base, thisValue, property)
249 USES(OpInstanceofCustom, value, constructor, hasInstanceValue)
250 USES(OpHasStructureProperty, base, property, enumerator)
251 USES(OpConstructVarargs, callee, thisValue, arguments)
252 USES(OpCallVarargs, callee, thisValue, arguments)
253 USES(OpTailCallVarargs, callee, thisValue, arguments)
254
255 USES(OpGetDirectPname, base, property, index, enumerator)
256
257 USES(OpSwitchString, scrutinee)
258 USES(OpSwitchChar, scrutinee)
259 USES(OpSwitchImm, scrutinee)
260
261 USES(OpGetInternalField, base)
262 USES(OpPutInternalField, base, value)
263
264 USES(OpYield, generator, argument)
265
266 case op_new_array_with_spread:
267 handleNewArrayLike(instruction->as<OpNewArrayWithSpread>());
268 return;
269 case op_new_array:
270 handleNewArrayLike(instruction->as<OpNewArray>());
271 return;
272
273 case op_strcat: {
274 auto bytecode = instruction->as<OpStrcat>();
275 int base = bytecode.m_src.offset();
276 for (int i = 0; i < bytecode.m_count; i++)
277 functor(VirtualRegister { base - i });
278 return;
279 }
280
281 case op_construct:
282 handleOpCallLike(instruction->as<OpConstruct>());
283 return;
284 case op_call_eval:
285 handleOpCallLike(instruction->as<OpCallEval>());
286 return;
287 case op_call:
288 handleOpCallLike(instruction->as<OpCall>());
289 return;
290 case op_tail_call:
291 handleOpCallLike(instruction->as<OpTailCall>());
292 return;
293
294 default:
295 RELEASE_ASSERT_NOT_REACHED();
296 break;
297 }
298}
299
300template<typename Block, typename Functor>
301void computeDefsForBytecodeIndex(Block* codeBlock, OpcodeID opcodeID, const Instruction* instruction, const Functor& functor)
302{
303 switch (opcodeID) {
304 case op_wide16:
305 case op_wide32:
306 RELEASE_ASSERT_NOT_REACHED();
307
308 // These don't define anything.
309 case op_put_to_scope:
310 case op_end:
311 case op_throw:
312 case op_throw_static_error:
313 case op_check_tdz:
314 case op_debug:
315 case op_ret:
316 case op_jmp:
317 case op_jtrue:
318 case op_jfalse:
319 case op_jeq_null:
320 case op_jneq_null:
321 case op_jundefined_or_null:
322 case op_jnundefined_or_null:
323 case op_jneq_ptr:
324 case op_jless:
325 case op_jlesseq:
326 case op_jgreater:
327 case op_jgreatereq:
328 case op_jnless:
329 case op_jnlesseq:
330 case op_jngreater:
331 case op_jngreatereq:
332 case op_jeq:
333 case op_jneq:
334 case op_jstricteq:
335 case op_jnstricteq:
336 case op_jbelow:
337 case op_jbeloweq:
338 case op_loop_hint:
339 case op_switch_imm:
340 case op_switch_char:
341 case op_switch_string:
342 case op_put_by_id:
343 case op_put_by_id_with_this:
344 case op_put_by_val_with_this:
345 case op_put_getter_by_id:
346 case op_put_setter_by_id:
347 case op_put_getter_setter_by_id:
348 case op_put_getter_by_val:
349 case op_put_setter_by_val:
350 case op_put_by_val:
351 case op_put_by_val_direct:
352 case op_put_internal_field:
353 case op_define_data_property:
354 case op_define_accessor_property:
355 case op_profile_type:
356 case op_profile_control_flow:
357 case op_put_to_arguments:
358 case op_set_function_name:
359 case op_check_traps:
360 case op_log_shadow_chicken_prologue:
361 case op_log_shadow_chicken_tail:
362 case op_yield:
363 case op_nop:
364 case op_unreachable:
365 case op_super_sampler_begin:
366 case op_super_sampler_end:
367#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
368 FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
369#undef LLINT_HELPER_OPCODES
370 return;
371 // These all have a single destination for the first argument.
372 DEFS(OpArgumentCount, dst)
373 DEFS(OpToIndexString, dst)
374 DEFS(OpGetEnumerableLength, dst)
375 DEFS(OpHasIndexedProperty, dst)
376 DEFS(OpHasStructureProperty, dst)
377 DEFS(OpHasGenericProperty, dst)
378 DEFS(OpGetDirectPname, dst)
379 DEFS(OpGetPropertyEnumerator, dst)
380 DEFS(OpEnumeratorStructurePname, dst)
381 DEFS(OpEnumeratorGenericPname, dst)
382 DEFS(OpGetParentScope, dst)
383 DEFS(OpPushWithScope, dst)
384 DEFS(OpCreateLexicalEnvironment, dst)
385 DEFS(OpCreateGeneratorFrameEnvironment, dst)
386 DEFS(OpResolveScope, dst)
387 DEFS(OpResolveScopeForHoistingFuncDeclInEval, dst)
388 DEFS(OpStrcat, dst)
389 DEFS(OpToPrimitive, dst)
390 DEFS(OpCreateThis, dst)
391 DEFS(OpCreatePromise, dst)
392 DEFS(OpCreateGenerator, dst)
393 DEFS(OpCreateAsyncGenerator, dst)
394 DEFS(OpNewArray, dst)
395 DEFS(OpNewArrayWithSpread, dst)
396 DEFS(OpSpread, dst)
397 DEFS(OpNewArrayBuffer, dst)
398 DEFS(OpNewArrayWithSize, dst)
399 DEFS(OpNewRegexp, dst)
400 DEFS(OpNewFunc, dst)
401 DEFS(OpNewFuncExp, dst)
402 DEFS(OpNewGeneratorFunc, dst)
403 DEFS(OpNewGeneratorFuncExp, dst)
404 DEFS(OpNewAsyncGeneratorFunc, dst)
405 DEFS(OpNewAsyncGeneratorFuncExp, dst)
406 DEFS(OpNewAsyncFunc, dst)
407 DEFS(OpNewAsyncFuncExp, dst)
408 DEFS(OpCallVarargs, dst)
409 DEFS(OpTailCallVarargs, dst)
410 DEFS(OpTailCallForwardArguments, dst)
411 DEFS(OpConstructVarargs, dst)
412 DEFS(OpGetFromScope, dst)
413 DEFS(OpCall, dst)
414 DEFS(OpTailCall, dst)
415 DEFS(OpCallEval, dst)
416 DEFS(OpConstruct, dst)
417 DEFS(OpTryGetById, dst)
418 DEFS(OpGetById, dst)
419 DEFS(OpGetByIdDirect, dst)
420 DEFS(OpGetByIdWithThis, dst)
421 DEFS(OpGetByValWithThis, dst)
422 DEFS(OpOverridesHasInstance, dst)
423 DEFS(OpInstanceof, dst)
424 DEFS(OpInstanceofCustom, dst)
425 DEFS(OpGetByVal, dst)
426 DEFS(OpTypeof, dst)
427 DEFS(OpIdentityWithProfile, srcDst)
428 DEFS(OpIsEmpty, dst)
429 DEFS(OpIsUndefined, dst)
430 USES(OpIsUndefinedOrNull, dst)
431 DEFS(OpIsBoolean, dst)
432 DEFS(OpIsNumber, dst)
433 DEFS(OpIsObject, dst)
434 DEFS(OpIsObjectOrNull, dst)
435 DEFS(OpIsCellWithType, dst)
436 DEFS(OpIsFunction, dst)
437 DEFS(OpInById, dst)
438 DEFS(OpInByVal, dst)
439 DEFS(OpToNumber, dst)
440 DEFS(OpToNumeric, dst)
441 DEFS(OpToString, dst)
442 DEFS(OpToObject, dst)
443 DEFS(OpNegate, dst)
444 DEFS(OpAdd, dst)
445 DEFS(OpMul, dst)
446 DEFS(OpDiv, dst)
447 DEFS(OpMod, dst)
448 DEFS(OpSub, dst)
449 DEFS(OpPow, dst)
450 DEFS(OpLshift, dst)
451 DEFS(OpRshift, dst)
452 DEFS(OpUrshift, dst)
453 DEFS(OpBitand, dst)
454 DEFS(OpBitxor, dst)
455 DEFS(OpBitor, dst)
456 DEFS(OpBitnot, dst)
457 DEFS(OpInc, srcDst)
458 DEFS(OpDec, srcDst)
459 DEFS(OpEq, dst)
460 DEFS(OpNeq, dst)
461 DEFS(OpStricteq, dst)
462 DEFS(OpNstricteq, dst)
463 DEFS(OpLess, dst)
464 DEFS(OpLesseq, dst)
465 DEFS(OpGreater, dst)
466 DEFS(OpGreatereq, dst)
467 DEFS(OpBelow, dst)
468 DEFS(OpBeloweq, dst)
469 DEFS(OpNeqNull, dst)
470 DEFS(OpEqNull, dst)
471 DEFS(OpNot, dst)
472 DEFS(OpMov, dst)
473 DEFS(OpNewObject, dst)
474 DEFS(OpNewPromise, dst)
475 DEFS(OpNewGenerator, dst)
476 DEFS(OpToThis, srcDst)
477 DEFS(OpGetScope, dst)
478 DEFS(OpCreateDirectArguments, dst)
479 DEFS(OpCreateScopedArguments, dst)
480 DEFS(OpCreateClonedArguments, dst)
481 DEFS(OpDelById, dst)
482 DEFS(OpDelByVal, dst)
483 DEFS(OpUnsigned, dst)
484 DEFS(OpGetFromArguments, dst)
485 DEFS(OpGetArgument, dst)
486 DEFS(OpCreateRest, dst)
487 DEFS(OpGetRestLength, dst)
488 DEFS(OpGetInternalField, dst)
489
490 DEFS(OpCatch, exception, thrownValue)
491
492 case op_enter: {
493 for (unsigned i = codeBlock->numVars(); i--;)
494 functor(virtualRegisterForLocal(i));
495 return;
496 }
497 }
498}
499
500#undef CALL_FUNCTOR
501#undef USES_OR_DEFS
502#undef USES
503#undef DEFS
504} // namespace JSC
505