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