Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / llint / LLIntSlowPaths.cpp
1 /*
2  * Copyright (C) 2011-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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "LLIntSlowPaths.h"
28
29 #include "ArrayConstructor.h"
30 #include "CallFrame.h"
31 #include "CommonSlowPaths.h"
32 #include "CommonSlowPathsExceptions.h"
33 #include "Error.h"
34 #include "ErrorHandlingScope.h"
35 #include "EvalCodeBlock.h"
36 #include "Exception.h"
37 #include "ExceptionFuzz.h"
38 #include "FrameTracers.h"
39 #include "FunctionCodeBlock.h"
40 #include "FunctionWhitelist.h"
41 #include "GetterSetter.h"
42 #include "HostCallReturnValue.h"
43 #include "InterpreterInlines.h"
44 #include "IteratorOperations.h"
45 #include "JIT.h"
46 #include "JITExceptions.h"
47 #include "JITWorklist.h"
48 #include "JSAsyncFunction.h"
49 #include "JSCInlines.h"
50 #include "JSCJSValue.h"
51 #include "JSGeneratorFunction.h"
52 #include "JSGlobalObjectFunctions.h"
53 #include "JSLexicalEnvironment.h"
54 #include "JSString.h"
55 #include "JSWithScope.h"
56 #include "LLIntCommon.h"
57 #include "LLIntData.h"
58 #include "LLIntExceptions.h"
59 #include "LowLevelInterpreter.h"
60 #include "ModuleProgramCodeBlock.h"
61 #include "ObjectConstructor.h"
62 #include "ObjectPropertyConditionSet.h"
63 #include "ProgramCodeBlock.h"
64 #include "ProtoCallFrame.h"
65 #include "RegExpObject.h"
66 #include "ShadowChicken.h"
67 #include "StructureRareDataInlines.h"
68 #include "VMInlines.h"
69 #include <wtf/NeverDestroyed.h>
70 #include <wtf/StringPrintStream.h>
71
72 namespace JSC { namespace LLInt {
73
74 #define LLINT_BEGIN_NO_SET_PC() \
75     VM& vm = exec->vm();      \
76     NativeCallFrameTracer tracer(&vm, exec); \
77     auto throwScope = DECLARE_THROW_SCOPE(vm)
78
79 #ifndef NDEBUG
80 #define LLINT_SET_PC_FOR_STUBS() do { \
81         exec->codeBlock()->bytecodeOffset(pc); \
82         exec->setCurrentVPC(pc); \
83     } while (false)
84 #else
85 #define LLINT_SET_PC_FOR_STUBS() do { \
86         exec->setCurrentVPC(pc); \
87     } while (false)
88 #endif
89
90 #define LLINT_BEGIN()                           \
91     LLINT_BEGIN_NO_SET_PC();                    \
92     LLINT_SET_PC_FOR_STUBS()
93
94 #define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
95 #define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
96
97 #define LLINT_RETURN_TWO(first, second) do {       \
98         return encodeResult(first, second);        \
99     } while (false)
100
101 #define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, 0)
102
103 #define LLINT_THROW(exceptionToThrow) do {                        \
104         throwException(exec, throwScope, exceptionToThrow);       \
105         pc = returnToThrow(exec);                                 \
106         LLINT_END_IMPL();                                         \
107     } while (false)
108
109 #define LLINT_CHECK_EXCEPTION() do {                    \
110         doExceptionFuzzingIfEnabled(exec, throwScope, "LLIntSlowPaths", pc);    \
111         if (UNLIKELY(throwScope.exception())) {         \
112             pc = returnToThrow(exec);                   \
113             LLINT_END_IMPL();                           \
114         }                                               \
115     } while (false)
116
117 #define LLINT_END() do {                        \
118         LLINT_CHECK_EXCEPTION();                \
119         LLINT_END_IMPL();                       \
120     } while (false)
121
122 #define LLINT_BRANCH(opcode, condition) do {                      \
123         bool __b_condition = (condition);                         \
124         LLINT_CHECK_EXCEPTION();                                  \
125         if (__b_condition)                                        \
126             pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand;        \
127         else                                                      \
128             pc += OPCODE_LENGTH(opcode);                          \
129         LLINT_END_IMPL();                                         \
130     } while (false)
131
132 #define LLINT_RETURN(value) do {                \
133         JSValue __r_returnValue = (value);      \
134         LLINT_CHECK_EXCEPTION();                \
135         LLINT_OP(1) = __r_returnValue;          \
136         LLINT_END_IMPL();                       \
137     } while (false)
138
139 #define LLINT_RETURN_WITH_PC_ADJUSTMENT(value, pcAdjustment) do { \
140         JSValue __r_returnValue = (value);      \
141         LLINT_CHECK_EXCEPTION();                \
142         LLINT_OP(1) = __r_returnValue;          \
143         pc += (pcAdjustment);                   \
144         LLINT_END_IMPL();                       \
145     } while (false)
146
147 #define LLINT_RETURN_PROFILED(opcode, value) do {               \
148         JSValue __rp_returnValue = (value);                     \
149         LLINT_CHECK_EXCEPTION();                                \
150         LLINT_OP(1) = __rp_returnValue;                         \
151         LLINT_PROFILE_VALUE(opcode, __rp_returnValue);          \
152         LLINT_END_IMPL();                                       \
153     } while (false)
154
155 #define LLINT_PROFILE_VALUE(opcode, value) do { \
156         pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
157         JSValue::encode(value);                  \
158     } while (false)
159
160 #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
161
162 #define LLINT_CALL_THROW(exec, exceptionToThrow) do {                   \
163         ExecState* __ct_exec = (exec);                                  \
164         throwException(__ct_exec, throwScope, exceptionToThrow);        \
165         LLINT_CALL_END_IMPL(0, callToThrow(__ct_exec));                 \
166     } while (false)
167
168 #define LLINT_CALL_CHECK_EXCEPTION(exec, execCallee) do {               \
169         ExecState* __cce_exec = (exec);                                 \
170         ExecState* __cce_execCallee = (execCallee);                     \
171         doExceptionFuzzingIfEnabled(__cce_exec, throwScope, "LLIntSlowPaths/call", nullptr); \
172         if (UNLIKELY(throwScope.exception()))                           \
173             LLINT_CALL_END_IMPL(0, callToThrow(__cce_execCallee));      \
174     } while (false)
175
176 #define LLINT_CALL_RETURN(exec, execCallee, callTarget) do {            \
177         ExecState* __cr_exec = (exec);                                  \
178         ExecState* __cr_execCallee = (execCallee);                      \
179         void* __cr_callTarget = (callTarget);                           \
180         LLINT_CALL_CHECK_EXCEPTION(__cr_exec, __cr_execCallee);         \
181         LLINT_CALL_END_IMPL(__cr_execCallee, __cr_callTarget);          \
182     } while (false)
183
184 #define LLINT_RETURN_CALLEE_FRAME(execCallee) do {                      \
185         ExecState* __rcf_exec = (execCallee);                           \
186         LLINT_RETURN_TWO(pc, __rcf_exec);                               \
187     } while (false)
188     
189 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
190 {
191     LLINT_BEGIN();
192     dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
193             exec->codeBlock(),
194             exec,
195             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
196             Interpreter::getOpcodeID(pc[0].u.opcode),
197             fromWhere,
198             operand,
199             pc[operand].u.operand);
200     LLINT_END();
201 }
202
203 extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
204 {
205     JSValue value = LLINT_OP_C(operand).jsValue();
206     union {
207         struct {
208             uint32_t tag;
209             uint32_t payload;
210         } bits;
211         EncodedJSValue asValue;
212     } u;
213     u.asValue = JSValue::encode(value);
214     dataLogF(
215         "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
216         exec->codeBlock(),
217         exec,
218         static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
219         Interpreter::getOpcodeID(pc[0].u.opcode),
220         fromWhere,
221         operand,
222         pc[operand].u.operand,
223         u.bits.tag,
224         u.bits.payload,
225         toCString(value).data());
226     LLINT_END_IMPL();
227 }
228
229 LLINT_SLOW_PATH_DECL(trace_prologue)
230 {
231     dataLogF("%p / %p: in prologue of ", exec->codeBlock(), exec);
232     dataLog(*exec->codeBlock(), "\n");
233     LLINT_END_IMPL();
234 }
235
236 static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
237 {
238     JSFunction* callee = jsCast<JSFunction*>(exec->jsCallee());
239     FunctionExecutable* executable = callee->jsExecutable();
240     CodeBlock* codeBlock = executable->codeBlockFor(kind);
241     dataLogF("%p / %p: in %s of ", codeBlock, exec, comment);
242     dataLog(*codeBlock);
243     dataLogF(" function %p, executable %p; numVars = %u, numParameters = %u, numCalleeLocals = %u, caller = %p.\n",
244         callee, executable, codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeLocals, exec->callerFrame());
245 }
246
247 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
248 {
249     traceFunctionPrologue(exec, "call prologue", CodeForCall);
250     LLINT_END_IMPL();
251 }
252
253 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
254 {
255     traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
256     LLINT_END_IMPL();
257 }
258
259 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
260 {
261     traceFunctionPrologue(exec, "call arity check", CodeForCall);
262     LLINT_END_IMPL();
263 }
264
265 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
266 {
267     traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
268     LLINT_END_IMPL();
269 }
270
271 LLINT_SLOW_PATH_DECL(trace)
272 {
273     OpcodeID opcodeID = Interpreter::getOpcodeID(pc[0].u.opcode);
274     dataLogF("%p / %p: executing bc#%zu, %s, pc = %p\n",
275             exec->codeBlock(),
276             exec,
277             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
278             opcodeNames[opcodeID], pc);
279     if (opcodeID == op_enter) {
280         dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
281         *bitwise_cast<volatile char*>(exec->returnPC().value());
282     }
283     if (opcodeID == op_ret) {
284         dataLogF("Will be returning to %p\n", exec->returnPC().value());
285         dataLogF("The new cfr will be %p\n", exec->callerFrame());
286     }
287     LLINT_END_IMPL();
288 }
289
290 LLINT_SLOW_PATH_DECL(special_trace)
291 {
292     dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
293             exec->codeBlock(),
294             exec,
295             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
296             Interpreter::getOpcodeID(pc[0].u.opcode),
297             exec->returnPC().value());
298     LLINT_END_IMPL();
299 }
300
301 enum EntryKind { Prologue, ArityCheck };
302
303 #if ENABLE(JIT)
304 static FunctionWhitelist& ensureGlobalJITWhitelist()
305 {
306     static LazyNeverDestroyed<FunctionWhitelist> baselineWhitelist;
307     static std::once_flag initializeWhitelistFlag;
308     std::call_once(initializeWhitelistFlag, [] {
309         const char* functionWhitelistFile = Options::jitWhitelist();
310         baselineWhitelist.construct(functionWhitelistFile);
311     });
312     return baselineWhitelist;
313 }
314
315 inline bool shouldJIT(ExecState* exec, CodeBlock* codeBlock)
316 {
317     if (!Options::bytecodeRangeToJITCompile().isInRange(codeBlock->instructionCount())
318         || !ensureGlobalJITWhitelist().contains(codeBlock))
319         return false;
320
321     // You can modify this to turn off JITting without rebuilding the world.
322     return exec->vm().canUseJIT();
323 }
324
325 // Returns true if we should try to OSR.
326 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec, unsigned loopOSREntryBytecodeOffset = 0)
327 {
328     VM& vm = exec->vm();
329     DeferGCForAWhile deferGC(vm.heap); // My callers don't set top callframe, so we don't want to GC here at all.
330     
331     codeBlock->updateAllValueProfilePredictions();
332
333     if (!codeBlock->checkIfJITThresholdReached()) {
334         CODEBLOCK_LOG_EVENT(codeBlock, "delayJITCompile", ("threshold not reached, counter = ", codeBlock->llintExecuteCounter()));
335         if (Options::verboseOSR())
336             dataLogF("    JIT threshold should be lifted.\n");
337         return false;
338     }
339     
340     JITWorklist::instance()->poll(vm);
341     
342     switch (codeBlock->jitType()) {
343     case JITCode::BaselineJIT: {
344         if (Options::verboseOSR())
345             dataLogF("    Code was already compiled.\n");
346         codeBlock->jitSoon();
347         return true;
348     }
349     case JITCode::InterpreterThunk: {
350         JITWorklist::instance()->compileLater(codeBlock, loopOSREntryBytecodeOffset);
351         return codeBlock->jitType() == JITCode::BaselineJIT;
352     }
353     default:
354         dataLog("Unexpected code block in LLInt: ", *codeBlock, "\n");
355         RELEASE_ASSERT_NOT_REACHED();
356         return false;
357     }
358 }
359
360 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
361 {
362     if (Options::verboseOSR()) {
363         dataLog(
364             *codeBlock, ": Entered ", name, " with executeCounter = ",
365             codeBlock->llintExecuteCounter(), "\n");
366     }
367     
368     if (!shouldJIT(exec, codeBlock)) {
369         codeBlock->dontJITAnytimeSoon();
370         LLINT_RETURN_TWO(0, 0);
371     }
372     if (!jitCompileAndSetHeuristics(codeBlock, exec))
373         LLINT_RETURN_TWO(0, 0);
374     
375     CODEBLOCK_LOG_EVENT(codeBlock, "OSR entry", ("in prologue"));
376     
377     if (kind == Prologue)
378         LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), 0);
379     ASSERT(kind == ArityCheck);
380     LLINT_RETURN_TWO(codeBlock->jitCode()->addressForCall(MustCheckArity).executableAddress(), 0);
381 }
382 #else // ENABLE(JIT)
383 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char*, EntryKind)
384 {
385     codeBlock->dontJITAnytimeSoon();
386     LLINT_RETURN_TWO(0, exec);
387 }
388 #endif // ENABLE(JIT)
389
390 LLINT_SLOW_PATH_DECL(entry_osr)
391 {
392     return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
393 }
394
395 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
396 {
397     return entryOSR(exec, pc, jsCast<JSFunction*>(exec->jsCallee())->jsExecutable()->codeBlockForCall(), "entry_osr_function_for_call", Prologue);
398 }
399
400 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
401 {
402     return entryOSR(exec, pc, jsCast<JSFunction*>(exec->jsCallee())->jsExecutable()->codeBlockForConstruct(), "entry_osr_function_for_construct", Prologue);
403 }
404
405 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
406 {
407     return entryOSR(exec, pc, jsCast<JSFunction*>(exec->jsCallee())->jsExecutable()->codeBlockForCall(), "entry_osr_function_for_call_arityCheck", ArityCheck);
408 }
409
410 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
411 {
412     return entryOSR(exec, pc, jsCast<JSFunction*>(exec->jsCallee())->jsExecutable()->codeBlockForConstruct(), "entry_osr_function_for_construct_arityCheck", ArityCheck);
413 }
414
415 LLINT_SLOW_PATH_DECL(loop_osr)
416 {
417     CodeBlock* codeBlock = exec->codeBlock();
418
419 #if ENABLE(JIT)
420     if (Options::verboseOSR()) {
421         dataLog(
422             *codeBlock, ": Entered loop_osr with executeCounter = ",
423             codeBlock->llintExecuteCounter(), "\n");
424     }
425     
426     unsigned loopOSREntryBytecodeOffset = pc - codeBlock->instructions().begin();
427
428     if (!shouldJIT(exec, codeBlock)) {
429         codeBlock->dontJITAnytimeSoon();
430         LLINT_RETURN_TWO(0, 0);
431     }
432     
433     if (!jitCompileAndSetHeuristics(codeBlock, exec, loopOSREntryBytecodeOffset))
434         LLINT_RETURN_TWO(0, 0);
435     
436     CODEBLOCK_LOG_EVENT(codeBlock, "osrEntry", ("at bc#", pc - codeBlock->instructions().begin()));
437
438     ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
439     
440     Vector<BytecodeAndMachineOffset> map;
441     codeBlock->jitCodeMap()->decode(map);
442     BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
443     ASSERT(mapping);
444     ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
445     
446     void* jumpTarget = codeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
447     ASSERT(jumpTarget);
448     
449     LLINT_RETURN_TWO(jumpTarget, exec->topOfFrame());
450 #else // ENABLE(JIT)
451     UNUSED_PARAM(pc);
452     codeBlock->dontJITAnytimeSoon();
453     LLINT_RETURN_TWO(0, 0);
454 #endif // ENABLE(JIT)
455 }
456
457 LLINT_SLOW_PATH_DECL(replace)
458 {
459     CodeBlock* codeBlock = exec->codeBlock();
460
461 #if ENABLE(JIT)
462     if (Options::verboseOSR()) {
463         dataLog(
464             *codeBlock, ": Entered replace with executeCounter = ",
465             codeBlock->llintExecuteCounter(), "\n");
466     }
467     
468     if (shouldJIT(exec, codeBlock))
469         jitCompileAndSetHeuristics(codeBlock, exec);
470     else
471         codeBlock->dontJITAnytimeSoon();
472     LLINT_END_IMPL();
473 #else // ENABLE(JIT)
474     codeBlock->dontJITAnytimeSoon();
475     LLINT_END_IMPL();
476 #endif // ENABLE(JIT)
477 }
478
479 LLINT_SLOW_PATH_DECL(stack_check)
480 {
481     VM& vm = exec->vm();
482     auto throwScope = DECLARE_THROW_SCOPE(vm);
483
484     VMEntryFrame* vmEntryFrame = vm.topVMEntryFrame;
485     CallFrame* callerFrame = exec->callerFrame(vmEntryFrame);
486     if (!callerFrame) {
487         callerFrame = exec;
488         vmEntryFrame = vm.topVMEntryFrame;
489     }
490     NativeCallFrameTracerWithRestore tracer(&vm, vmEntryFrame, callerFrame);
491
492     LLINT_SET_PC_FOR_STUBS();
493
494 #if LLINT_SLOW_PATH_TRACING
495     dataLogF("Checking stack height with exec = %p.\n", exec);
496     dataLog("CodeBlock = ", *exec->codeBlock(), "\n");
497     dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeLocals);
498     dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
499
500     dataLogF("Current OS stack end is at %p.\n", vm.softStackLimit());
501 #if !ENABLE(JIT)
502     dataLogF("Current C Loop stack end is at %p.\n", vm.cloopStackLimit());
503 #endif
504
505 #endif
506     // If the stack check succeeds and we don't need to throw the error, then
507     // we'll return 0 instead. The prologue will check for a non-zero value
508     // when determining whether to set the callFrame or not.
509
510     // For JIT enabled builds which uses the C stack, the stack is not growable.
511     // Hence, if we get here, then we know a stack overflow is imminent. So, just
512     // throw the StackOverflowError unconditionally.
513 #if !ENABLE(JIT)
514     ASSERT(!vm.interpreter->cloopStack().containsAddress(exec->topOfFrame()));
515     if (LIKELY(vm.ensureStackCapacityFor(exec->topOfFrame())))
516         LLINT_RETURN_TWO(pc, 0);
517 #endif
518
519     ErrorHandlingScope errorScope(vm);
520     throwStackOverflowError(callerFrame, throwScope);
521     pc = returnToThrow(callerFrame);
522     LLINT_RETURN_TWO(pc, exec);
523 }
524
525 LLINT_SLOW_PATH_DECL(slow_path_new_object)
526 {
527     LLINT_BEGIN();
528     LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
529 }
530
531 LLINT_SLOW_PATH_DECL(slow_path_new_array)
532 {
533     LLINT_BEGIN();
534     LLINT_RETURN(constructArrayNegativeIndexed(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
535 }
536
537 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
538 {
539     LLINT_BEGIN();
540     LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
541 }
542
543 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
544 {
545     LLINT_BEGIN();
546     LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
547 }
548
549 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
550 {
551     LLINT_BEGIN();
552     RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
553     if (!regExp->isValid())
554         LLINT_THROW(createSyntaxError(exec, regExp->errorMessage()));
555     LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regExp));
556 }
557
558 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
559 {
560     LLINT_BEGIN();
561     JSValue value = LLINT_OP_C(2).jsValue();
562     JSValue proto = LLINT_OP_C(3).jsValue();
563     LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
564 }
565
566 LLINT_SLOW_PATH_DECL(slow_path_instanceof_custom)
567 {
568     LLINT_BEGIN();
569
570     JSValue value = LLINT_OP_C(2).jsValue();
571     JSValue constructor = LLINT_OP_C(3).jsValue();
572     JSValue hasInstanceValue = LLINT_OP_C(4).jsValue();
573
574     ASSERT(constructor.isObject());
575     ASSERT(hasInstanceValue != exec->lexicalGlobalObject()->functionProtoHasInstanceSymbolFunction() || !constructor.getObject()->structure()->typeInfo().implementsDefaultHasInstance());
576
577     JSValue result = jsBoolean(constructor.getObject()->hasInstance(exec, value, hasInstanceValue));
578     LLINT_RETURN(result);
579 }
580
581 LLINT_SLOW_PATH_DECL(slow_path_try_get_by_id)
582 {
583     LLINT_BEGIN();
584     CodeBlock* codeBlock = exec->codeBlock();
585     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
586     JSValue baseValue = LLINT_OP_C(2).jsValue();
587     PropertySlot slot(baseValue, PropertySlot::PropertySlot::InternalMethodType::VMInquiry);
588
589     baseValue.getPropertySlot(exec, ident, slot);
590     JSValue result = slot.getPureResult();
591
592     LLINT_RETURN_PROFILED(op_try_get_by_id, result);
593 }
594
595 static void setupGetByIdPrototypeCache(ExecState* exec, VM& vm, Instruction* pc, JSCell* baseCell, PropertySlot& slot, const Identifier& ident)
596 {
597     CodeBlock* codeBlock = exec->codeBlock();
598     Structure* structure = baseCell->structure();
599
600     if (structure->typeInfo().prohibitsPropertyCaching())
601         return;
602     
603     if (structure->needImpurePropertyWatchpoint())
604         return;
605
606     if (structure->isDictionary()) {
607         if (structure->hasBeenFlattenedBefore())
608             return;
609         structure->flattenDictionaryStructure(vm, jsCast<JSObject*>(baseCell));
610     }
611
612     ObjectPropertyConditionSet conditions;
613     if (slot.isUnset())
614         conditions = generateConditionsForPropertyMiss(vm, codeBlock, exec, structure, ident.impl());
615     else
616         conditions = generateConditionsForPrototypePropertyHit(vm, codeBlock, exec, structure, slot.slotBase(), ident.impl());
617
618     if (!conditions.isValid())
619         return;
620
621     PropertyOffset offset = invalidOffset;
622     CodeBlock::StructureWatchpointMap& watchpointMap = codeBlock->llintGetByIdWatchpointMap();
623     auto result = watchpointMap.add(structure, Bag<LLIntPrototypeLoadAdaptiveStructureWatchpoint>());
624     for (ObjectPropertyCondition condition : conditions) {
625         if (!condition.isWatchable())
626             return;
627         if (condition.condition().kind() == PropertyCondition::Presence)
628             offset = condition.condition().offset();
629         result.iterator->value.add(condition, pc)->install();
630     }
631     ASSERT((offset == invalidOffset) == slot.isUnset());
632
633     ConcurrentJSLocker locker(codeBlock->m_lock);
634
635     if (slot.isUnset()) {
636         pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_unset);
637         pc[4].u.structureID = structure->id();
638         return;
639     }
640     ASSERT(slot.isValue());
641
642     pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_proto_load);
643     pc[4].u.structureID = structure->id();
644     pc[5].u.operand = offset;
645     // We know that this pointer will remain valid because it will be cleared by either a watchpoint fire or
646     // during GC when we clear the LLInt caches.
647     pc[6].u.pointer = slot.slotBase();
648 }
649
650
651 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
652 {
653     LLINT_BEGIN();
654     CodeBlock* codeBlock = exec->codeBlock();
655     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
656     JSValue baseValue = LLINT_OP_C(2).jsValue();
657     PropertySlot slot(baseValue, PropertySlot::PropertySlot::InternalMethodType::Get);
658
659     JSValue result = baseValue.get(exec, ident, slot);
660     LLINT_CHECK_EXCEPTION();
661     LLINT_OP(1) = result;
662     
663     if (!LLINT_ALWAYS_ACCESS_SLOW
664         && baseValue.isCell()
665         && slot.isCacheable()) {
666
667         JSCell* baseCell = baseValue.asCell();
668         Structure* structure = baseCell->structure();
669         if (slot.isValue() && slot.slotBase() == baseValue) {
670             // Start out by clearing out the old cache.
671             pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
672             pc[4].u.pointer = nullptr; // old structure
673             pc[5].u.pointer = nullptr; // offset
674
675             // Prevent the prototype cache from ever happening.
676             pc[7].u.operand = 0;
677         
678             if (structure->propertyAccessesAreCacheable()
679                 && !structure->needImpurePropertyWatchpoint()) {
680                 vm.heap.writeBarrier(codeBlock);
681                 
682                 ConcurrentJSLocker locker(codeBlock->m_lock);
683
684                 pc[4].u.structureID = structure->id();
685                 pc[5].u.operand = slot.cachedOffset();
686             }
687         } else if (UNLIKELY(pc[7].u.operand && (slot.isValue() || slot.isUnset()))) {
688             ASSERT(slot.slotBase() != baseValue);
689
690             if (!(--pc[7].u.operand))
691                 setupGetByIdPrototypeCache(exec, vm, pc, baseCell, slot, ident);
692         }
693     } else if (!LLINT_ALWAYS_ACCESS_SLOW
694         && isJSArray(baseValue)
695         && ident == exec->propertyNames().length) {
696         pc[0].u.opcode = LLInt::getOpcode(op_get_array_length);
697         ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
698         arrayProfile->observeStructure(baseValue.asCell()->structure());
699         pc[4].u.arrayProfile = arrayProfile;
700
701         // Prevent the prototype cache from ever happening.
702         pc[7].u.operand = 0;
703     }
704
705     pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
706     LLINT_END();
707 }
708
709 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
710 {
711     LLINT_BEGIN();
712     CodeBlock* codeBlock = exec->codeBlock();
713     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
714     JSValue baseValue = LLINT_OP(2).jsValue();
715     PropertySlot slot(baseValue, PropertySlot::InternalMethodType::Get);
716     LLINT_RETURN(baseValue.get(exec, ident, slot));
717 }
718
719 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
720 {
721     LLINT_BEGIN();
722     CodeBlock* codeBlock = exec->codeBlock();
723     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
724     
725     JSValue baseValue = LLINT_OP_C(1).jsValue();
726     PutPropertySlot slot(baseValue, codeBlock->isStrictMode(), codeBlock->putByIdContext());
727     if (pc[8].u.putByIdFlags & PutByIdIsDirect)
728         asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
729     else
730         baseValue.putInline(exec, ident, LLINT_OP_C(3).jsValue(), slot);
731     LLINT_CHECK_EXCEPTION();
732     
733     if (!LLINT_ALWAYS_ACCESS_SLOW
734         && baseValue.isCell()
735         && slot.isCacheablePut()) {
736
737         // Start out by clearing out the old cache.
738         pc[4].u.pointer = nullptr; // old structure
739         pc[5].u.pointer = nullptr; // offset
740         pc[6].u.pointer = nullptr; // new structure
741         pc[7].u.pointer = nullptr; // structure chain
742         pc[8].u.putByIdFlags =
743             static_cast<PutByIdFlags>(pc[8].u.putByIdFlags & PutByIdPersistentFlagsMask);
744         
745         JSCell* baseCell = baseValue.asCell();
746         Structure* structure = baseCell->structure();
747         
748         if (!structure->isUncacheableDictionary()
749             && !structure->typeInfo().prohibitsPropertyCaching()
750             && baseCell == slot.base()) {
751
752             vm.heap.writeBarrier(codeBlock);
753             
754             if (slot.type() == PutPropertySlot::NewProperty) {
755                 GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
756             
757                 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
758                     ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
759
760                     if (normalizePrototypeChain(exec, structure) != InvalidPrototypeChain) {
761                         ASSERT(structure->previousID()->isObject());
762                         pc[4].u.structureID = structure->previousID()->id();
763                         pc[5].u.operand = slot.cachedOffset();
764                         pc[6].u.structureID = structure->id();
765                         if (!(pc[8].u.putByIdFlags & PutByIdIsDirect)) {
766                             StructureChain* chain = structure->prototypeChain(exec);
767                             ASSERT(chain);
768                             pc[7].u.structureChain.set(
769                                 vm, codeBlock, chain);
770                         }
771                         pc[8].u.putByIdFlags = static_cast<PutByIdFlags>(
772                             pc[8].u.putByIdFlags |
773                             structure->inferredTypeDescriptorFor(ident.impl()).putByIdFlags());
774                     }
775                 }
776             } else {
777                 structure->didCachePropertyReplacement(vm, slot.cachedOffset());
778                 pc[4].u.structureID = structure->id();
779                 pc[5].u.operand = slot.cachedOffset();
780                 pc[8].u.putByIdFlags = static_cast<PutByIdFlags>(
781                     pc[8].u.putByIdFlags |
782                     structure->inferredTypeDescriptorFor(ident.impl()).putByIdFlags());
783             }
784         }
785     }
786     
787     LLINT_END();
788 }
789
790 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
791 {
792     LLINT_BEGIN();
793     CodeBlock* codeBlock = exec->codeBlock();
794     JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
795     LLINT_CHECK_EXCEPTION();
796     bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
797     LLINT_CHECK_EXCEPTION();
798     if (!couldDelete && codeBlock->isStrictMode())
799         LLINT_THROW(createTypeError(exec, UnableToDeletePropertyError));
800     LLINT_RETURN(jsBoolean(couldDelete));
801 }
802
803 static ALWAYS_INLINE JSValue getByVal(VM& vm, ExecState* exec, JSValue baseValue, JSValue subscript)
804 {
805     auto scope = DECLARE_THROW_SCOPE(vm);
806
807     if (LIKELY(baseValue.isCell() && subscript.isString())) {
808         Structure& structure = *baseValue.asCell()->structure(vm);
809         if (JSCell::canUseFastGetOwnProperty(structure)) {
810             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
811                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
812                     return result;
813             }
814         }
815     }
816     
817     if (subscript.isUInt32()) {
818         uint32_t i = subscript.asUInt32();
819         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
820             return asString(baseValue)->getIndex(exec, i);
821         scope.release();
822         return baseValue.get(exec, i);
823     }
824
825     baseValue.requireObjectCoercible(exec);
826     RETURN_IF_EXCEPTION(scope, JSValue());
827     auto property = subscript.toPropertyKey(exec);
828     RETURN_IF_EXCEPTION(scope, JSValue());
829     scope.release();
830     return baseValue.get(exec, property);
831 }
832
833 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
834 {
835     LLINT_BEGIN();
836     LLINT_RETURN_PROFILED(op_get_by_val, getByVal(vm, exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
837 }
838
839 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
840 {
841     LLINT_BEGIN();
842     
843     JSValue baseValue = LLINT_OP_C(1).jsValue();
844     JSValue subscript = LLINT_OP_C(2).jsValue();
845     JSValue value = LLINT_OP_C(3).jsValue();
846     bool isStrictMode = exec->codeBlock()->isStrictMode();
847     
848     if (LIKELY(subscript.isUInt32())) {
849         uint32_t i = subscript.asUInt32();
850         if (baseValue.isObject()) {
851             JSObject* object = asObject(baseValue);
852             if (object->canSetIndexQuickly(i))
853                 object->setIndexQuickly(vm, i, value);
854             else
855                 object->methodTable()->putByIndex(object, exec, i, value, isStrictMode);
856             LLINT_END();
857         }
858         baseValue.putByIndex(exec, i, value, isStrictMode);
859         LLINT_END();
860     }
861
862     auto property = subscript.toPropertyKey(exec);
863     LLINT_CHECK_EXCEPTION();
864     PutPropertySlot slot(baseValue, isStrictMode);
865     baseValue.put(exec, property, value, slot);
866     LLINT_END();
867 }
868
869 LLINT_SLOW_PATH_DECL(slow_path_put_by_val_direct)
870 {
871     LLINT_BEGIN();
872     
873     JSValue baseValue = LLINT_OP_C(1).jsValue();
874     JSValue subscript = LLINT_OP_C(2).jsValue();
875     JSValue value = LLINT_OP_C(3).jsValue();
876     RELEASE_ASSERT(baseValue.isObject());
877     JSObject* baseObject = asObject(baseValue);
878     bool isStrictMode = exec->codeBlock()->isStrictMode();
879     if (LIKELY(subscript.isUInt32())) {
880         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
881         ASSERT(isIndex(subscript.asUInt32()));
882         baseObject->putDirectIndex(exec, subscript.asUInt32(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
883         LLINT_END();
884     }
885
886     if (subscript.isDouble()) {
887         double subscriptAsDouble = subscript.asDouble();
888         uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
889         if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
890             baseObject->putDirectIndex(exec, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
891             LLINT_END();
892         }
893     }
894
895     // Don't put to an object if toString threw an exception.
896     auto property = subscript.toPropertyKey(exec);
897     if (UNLIKELY(throwScope.exception()))
898         LLINT_END();
899
900     if (std::optional<uint32_t> index = parseIndex(property))
901         baseObject->putDirectIndex(exec, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
902     else {
903         PutPropertySlot slot(baseObject, isStrictMode);
904         baseObject->putDirect(exec->vm(), property, value, slot);
905     }
906     LLINT_END();
907 }
908
909 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
910 {
911     LLINT_BEGIN();
912     JSValue baseValue = LLINT_OP_C(2).jsValue();
913     JSObject* baseObject = baseValue.toObject(exec);
914     LLINT_CHECK_EXCEPTION();
915
916     JSValue subscript = LLINT_OP_C(3).jsValue();
917     
918     bool couldDelete;
919     
920     uint32_t i;
921     if (subscript.getUInt32(i))
922         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
923     else {
924         LLINT_CHECK_EXCEPTION();
925         auto property = subscript.toPropertyKey(exec);
926         LLINT_CHECK_EXCEPTION();
927         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
928     }
929     
930     if (!couldDelete && exec->codeBlock()->isStrictMode())
931         LLINT_THROW(createTypeError(exec, UnableToDeletePropertyError));
932     
933     LLINT_RETURN(jsBoolean(couldDelete));
934 }
935
936 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
937 {
938     LLINT_BEGIN();
939     JSValue arrayValue = LLINT_OP_C(1).jsValue();
940     ASSERT(isJSArray(arrayValue));
941     asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
942     LLINT_END();
943 }
944
945 LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
946 {
947     LLINT_BEGIN();
948     ASSERT(LLINT_OP(1).jsValue().isObject());
949     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
950
951     unsigned options = pc[3].u.operand;
952
953     JSValue getter = LLINT_OP(4).jsValue();
954     ASSERT(getter.isObject());
955
956     baseObj->putGetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(getter), options);
957     LLINT_END();
958 }
959
960 LLINT_SLOW_PATH_DECL(slow_path_put_setter_by_id)
961 {
962     LLINT_BEGIN();
963     ASSERT(LLINT_OP(1).jsValue().isObject());
964     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
965
966     unsigned options = pc[3].u.operand;
967
968     JSValue setter = LLINT_OP(4).jsValue();
969     ASSERT(setter.isObject());
970
971     baseObj->putSetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(setter), options);
972     LLINT_END();
973 }
974
975 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter_by_id)
976 {
977     LLINT_BEGIN();
978     ASSERT(LLINT_OP(1).jsValue().isObject());
979     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
980     
981     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
982     LLINT_CHECK_EXCEPTION();
983
984     JSValue getter = LLINT_OP(4).jsValue();
985     JSValue setter = LLINT_OP(5).jsValue();
986     ASSERT(getter.isObject() || getter.isUndefined());
987     ASSERT(setter.isObject() || setter.isUndefined());
988     ASSERT(getter.isObject() || setter.isObject());
989     
990     if (!getter.isUndefined())
991         accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
992     if (!setter.isUndefined())
993         accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
994     baseObj->putDirectAccessor(
995         exec,
996         exec->codeBlock()->identifier(pc[2].u.operand),
997         accessor, pc[3].u.operand);
998     LLINT_END();
999 }
1000
1001 LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_val)
1002 {
1003     LLINT_BEGIN();
1004     ASSERT(LLINT_OP(1).jsValue().isObject());
1005     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1006     JSValue subscript = LLINT_OP_C(2).jsValue();
1007
1008     unsigned options = pc[3].u.operand;
1009
1010     JSValue getter = LLINT_OP(4).jsValue();
1011     ASSERT(getter.isObject());
1012
1013     auto property = subscript.toPropertyKey(exec);
1014     LLINT_CHECK_EXCEPTION();
1015
1016     baseObj->putGetter(exec, property, asObject(getter), options);
1017     LLINT_END();
1018 }
1019
1020 LLINT_SLOW_PATH_DECL(slow_path_put_setter_by_val)
1021 {
1022     LLINT_BEGIN();
1023     ASSERT(LLINT_OP(1).jsValue().isObject());
1024     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1025     JSValue subscript = LLINT_OP_C(2).jsValue();
1026
1027     unsigned options = pc[3].u.operand;
1028
1029     JSValue setter = LLINT_OP(4).jsValue();
1030     ASSERT(setter.isObject());
1031
1032     auto property = subscript.toPropertyKey(exec);
1033     LLINT_CHECK_EXCEPTION();
1034
1035     baseObj->putSetter(exec, property, asObject(setter), options);
1036     LLINT_END();
1037 }
1038
1039 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
1040 {
1041     LLINT_BEGIN();
1042     LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
1043 }
1044
1045 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
1046 {
1047     LLINT_BEGIN();
1048     LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
1049 }
1050
1051 LLINT_SLOW_PATH_DECL(slow_path_jless)
1052 {
1053     LLINT_BEGIN();
1054     LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1055 }
1056
1057 LLINT_SLOW_PATH_DECL(slow_path_jnless)
1058 {
1059     LLINT_BEGIN();
1060     LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1061 }
1062
1063 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
1064 {
1065     LLINT_BEGIN();
1066     LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1067 }
1068
1069 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
1070 {
1071     LLINT_BEGIN();
1072     LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1073 }
1074
1075 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
1076 {
1077     LLINT_BEGIN();
1078     LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1079 }
1080
1081 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
1082 {
1083     LLINT_BEGIN();
1084     LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1085 }
1086
1087 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
1088 {
1089     LLINT_BEGIN();
1090     LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1091 }
1092
1093 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
1094 {
1095     LLINT_BEGIN();
1096     LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1097 }
1098
1099 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
1100 {
1101     LLINT_BEGIN();
1102     JSValue scrutinee = LLINT_OP_C(3).jsValue();
1103     ASSERT(scrutinee.isDouble());
1104     double value = scrutinee.asDouble();
1105     int32_t intValue = static_cast<int32_t>(value);
1106     int defaultOffset = pc[2].u.operand;
1107     if (value == intValue) {
1108         CodeBlock* codeBlock = exec->codeBlock();
1109         pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
1110     } else
1111         pc += defaultOffset;
1112     LLINT_END();
1113 }
1114
1115 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
1116 {
1117     LLINT_BEGIN();
1118     JSValue scrutinee = LLINT_OP_C(3).jsValue();
1119     ASSERT(scrutinee.isString());
1120     JSString* string = asString(scrutinee);
1121     ASSERT(string->length() == 1);
1122     int defaultOffset = pc[2].u.operand;
1123     StringImpl* impl = string->value(exec).impl();
1124     CodeBlock* codeBlock = exec->codeBlock();
1125     pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
1126     LLINT_END();
1127 }
1128
1129 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
1130 {
1131     LLINT_BEGIN();
1132     JSValue scrutinee = LLINT_OP_C(3).jsValue();
1133     int defaultOffset = pc[2].u.operand;
1134     if (!scrutinee.isString())
1135         pc += defaultOffset;
1136     else {
1137         CodeBlock* codeBlock = exec->codeBlock();
1138         pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1139     }
1140     LLINT_END();
1141 }
1142
1143 LLINT_SLOW_PATH_DECL(slow_path_new_func)
1144 {
1145     LLINT_BEGIN();
1146     CodeBlock* codeBlock = exec->codeBlock();
1147     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1148 #if LLINT_SLOW_PATH_TRACING
1149     dataLogF("Creating function!\n");
1150 #endif
1151     LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
1152 }
1153
1154 LLINT_SLOW_PATH_DECL(slow_path_new_generator_func)
1155 {
1156     LLINT_BEGIN();
1157     CodeBlock* codeBlock = exec->codeBlock();
1158     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1159 #if LLINT_SLOW_PATH_TRACING
1160     dataLogF("Creating function!\n");
1161 #endif
1162     LLINT_RETURN(JSGeneratorFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
1163 }
1164
1165 LLINT_SLOW_PATH_DECL(slow_path_new_async_func)
1166 {
1167     LLINT_BEGIN();
1168     CodeBlock* codeBlock = exec->codeBlock();
1169     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1170 #if LLINT_SLOW_PATH_TRACING
1171     dataLogF("Creating async function!\n");
1172 #endif
1173     LLINT_RETURN(JSAsyncFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
1174 }
1175
1176 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1177 {
1178     LLINT_BEGIN();
1179     
1180     CodeBlock* codeBlock = exec->codeBlock();
1181     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1182     FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
1183     
1184     LLINT_RETURN(JSFunction::create(vm, executable, scope));
1185 }
1186
1187 LLINT_SLOW_PATH_DECL(slow_path_new_generator_func_exp)
1188 {
1189     LLINT_BEGIN();
1190
1191     CodeBlock* codeBlock = exec->codeBlock();
1192     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1193     FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
1194
1195     LLINT_RETURN(JSGeneratorFunction::create(vm, executable, scope));
1196 }
1197
1198 LLINT_SLOW_PATH_DECL(slow_path_new_async_func_exp)
1199 {
1200     LLINT_BEGIN();
1201     
1202     CodeBlock* codeBlock = exec->codeBlock();
1203     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1204     FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
1205     
1206     LLINT_RETURN(JSAsyncFunction::create(vm, executable, scope));
1207 }
1208
1209 LLINT_SLOW_PATH_DECL(slow_path_set_function_name)
1210 {
1211     LLINT_BEGIN();
1212     JSFunction* func = jsCast<JSFunction*>(LLINT_OP(1).Register::unboxedCell());
1213     JSValue name = LLINT_OP_C(2).Register::jsValue();
1214     func->setFunctionName(exec, name);
1215     LLINT_END();
1216 }
1217
1218 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1219 {
1220     UNUSED_PARAM(pc);
1221
1222 #if LLINT_SLOW_PATH_TRACING
1223     dataLog("Performing host call.\n");
1224 #endif
1225     
1226     ExecState* exec = execCallee->callerFrame();
1227     VM& vm = exec->vm();
1228     auto throwScope = DECLARE_THROW_SCOPE(vm);
1229
1230     execCallee->setCodeBlock(0);
1231     execCallee->clearReturnPC();
1232
1233     if (kind == CodeForCall) {
1234         CallData callData;
1235         CallType callType = getCallData(callee, callData);
1236     
1237         ASSERT(callType != CallType::JS);
1238     
1239         if (callType == CallType::Host) {
1240             NativeCallFrameTracer tracer(&vm, execCallee);
1241             execCallee->setCallee(asObject(callee));
1242             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1243             
1244             LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1245         }
1246         
1247 #if LLINT_SLOW_PATH_TRACING
1248         dataLog("Call callee is not a function: ", callee, "\n");
1249 #endif
1250
1251         ASSERT(callType == CallType::None);
1252         LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
1253     }
1254
1255     ASSERT(kind == CodeForConstruct);
1256     
1257     ConstructData constructData;
1258     ConstructType constructType = getConstructData(callee, constructData);
1259     
1260     ASSERT(constructType != ConstructType::JS);
1261     
1262     if (constructType == ConstructType::Host) {
1263         NativeCallFrameTracer tracer(&vm, execCallee);
1264         execCallee->setCallee(asObject(callee));
1265         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1266
1267         LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1268     }
1269     
1270 #if LLINT_SLOW_PATH_TRACING
1271     dataLog("Constructor callee is not a function: ", callee, "\n");
1272 #endif
1273
1274     ASSERT(constructType == ConstructType::None);
1275     LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1276 }
1277
1278 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1279 {
1280     ExecState* exec = execCallee->callerFrame();
1281     VM& vm = exec->vm();
1282     auto throwScope = DECLARE_THROW_SCOPE(vm);
1283
1284 #if LLINT_SLOW_PATH_TRACING
1285     dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
1286 #endif
1287     
1288     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1289     if (!calleeAsFunctionCell) {
1290         throwScope.release();
1291         return handleHostCall(execCallee, pc, calleeAsValue, kind);
1292     }
1293     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1294     JSScope* scope = callee->scopeUnchecked();
1295     ExecutableBase* executable = callee->executable();
1296
1297     MacroAssemblerCodePtr codePtr;
1298     CodeBlock* codeBlock = 0;
1299     if (executable->isHostFunction()) {
1300         codePtr = executable->entrypointFor(kind, MustCheckArity);
1301     } else {
1302         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1303
1304         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
1305             LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1306
1307         CodeBlock** codeBlockSlot = execCallee->addressOfCodeBlock();
1308         JSObject* error = functionExecutable->prepareForExecution<FunctionExecutable>(vm, callee, scope, kind, *codeBlockSlot);
1309         ASSERT(throwScope.exception() == error);
1310         if (UNLIKELY(error))
1311             LLINT_CALL_THROW(exec, error);
1312         codeBlock = *codeBlockSlot;
1313         ASSERT(codeBlock);
1314         ArityCheckMode arity;
1315         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1316             arity = MustCheckArity;
1317         else
1318             arity = ArityCheckNotRequired;
1319         codePtr = functionExecutable->entrypointFor(kind, arity);
1320     }
1321
1322     ASSERT(!!codePtr);
1323     
1324     if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1325         CodeBlock* callerCodeBlock = exec->codeBlock();
1326
1327         ConcurrentJSLocker locker(callerCodeBlock->m_lock);
1328         
1329         if (callLinkInfo->isOnList())
1330             callLinkInfo->remove();
1331         callLinkInfo->callee.set(vm, callerCodeBlock, callee);
1332         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock, callee);
1333         callLinkInfo->machineCodeTarget = codePtr;
1334         if (codeBlock)
1335             codeBlock->linkIncomingCall(exec, callLinkInfo);
1336     }
1337
1338     LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
1339 }
1340
1341 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1342 {
1343     // This needs to:
1344     // - Set up a call frame.
1345     // - Figure out what to call and compile it if necessary.
1346     // - If possible, link the call's inline cache.
1347     // - Return a tuple of machine code address to call and the new call frame.
1348     
1349     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1350     
1351     ExecState* execCallee = exec - pc[4].u.operand;
1352     
1353     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1354     execCallee->uncheckedR(CallFrameSlot::callee) = calleeAsValue;
1355     execCallee->setCallerFrame(exec);
1356     
1357     ASSERT(pc[5].u.callLinkInfo);
1358     return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1359 }
1360
1361 LLINT_SLOW_PATH_DECL(slow_path_call)
1362 {
1363     LLINT_BEGIN_NO_SET_PC();
1364     throwScope.release();
1365     return genericCall(exec, pc, CodeForCall);
1366 }
1367
1368 LLINT_SLOW_PATH_DECL(slow_path_construct)
1369 {
1370     LLINT_BEGIN_NO_SET_PC();
1371     throwScope.release();
1372     return genericCall(exec, pc, CodeForConstruct);
1373 }
1374
1375 LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_varargs)
1376 {
1377     LLINT_BEGIN();
1378     // This needs to:
1379     // - Set up a call frame while respecting the variable arguments.
1380     
1381     unsigned numUsedStackSlots = -pc[5].u.operand;
1382     unsigned length = sizeFrameForVarargs(exec, vm,
1383         LLINT_OP_C(4).jsValue(), numUsedStackSlots, pc[6].u.operand);
1384     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1385     
1386     ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, length + 1);
1387     vm.varargsLength = length;
1388     vm.newCallFrameReturnValue = execCallee;
1389
1390     LLINT_RETURN_CALLEE_FRAME(execCallee);
1391 }
1392
1393 LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_forward_arguments)
1394 {
1395     LLINT_BEGIN();
1396     // This needs to:
1397     // - Set up a call frame with the same arguments as the current frame.
1398
1399     unsigned numUsedStackSlots = -pc[5].u.operand;
1400
1401     unsigned arguments = sizeFrameForForwardArguments(exec, vm, numUsedStackSlots);
1402     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1403
1404     ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, arguments + 1);
1405
1406     vm.varargsLength = arguments;
1407     vm.newCallFrameReturnValue = execCallee;
1408
1409     LLINT_RETURN_CALLEE_FRAME(execCallee);
1410 }
1411
1412 enum class SetArgumentsWith {
1413     Object,
1414     CurrentArguments
1415 };
1416
1417 inline SlowPathReturnType varargsSetup(ExecState* exec, Instruction* pc, CodeSpecializationKind kind, SetArgumentsWith set)
1418 {
1419     LLINT_BEGIN_NO_SET_PC();
1420     // This needs to:
1421     // - Figure out what to call and compile it if necessary.
1422     // - Return a tuple of machine code address to call and the new call frame.
1423
1424     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1425
1426     ExecState* execCallee = vm.newCallFrameReturnValue;
1427
1428     if (set == SetArgumentsWith::Object) {
1429         setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
1430         LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1431     } else
1432         setupForwardArgumentsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), vm.varargsLength);
1433
1434     execCallee->setCallerFrame(exec);
1435     execCallee->uncheckedR(CallFrameSlot::callee) = calleeAsValue;
1436     exec->setCurrentVPC(pc);
1437
1438     throwScope.release();
1439     return setUpCall(execCallee, pc, kind, calleeAsValue);
1440 }
1441
1442 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1443 {
1444     return varargsSetup(exec, pc, CodeForCall, SetArgumentsWith::Object);
1445 }
1446
1447 LLINT_SLOW_PATH_DECL(slow_path_tail_call_forward_arguments)
1448 {
1449     return varargsSetup(exec, pc, CodeForCall, SetArgumentsWith::CurrentArguments);
1450 }
1451
1452 LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
1453 {
1454     return varargsSetup(exec, pc, CodeForConstruct, SetArgumentsWith::Object);
1455 }
1456
1457     
1458 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1459 {
1460     LLINT_BEGIN_NO_SET_PC();
1461     JSValue calleeAsValue = LLINT_OP(2).jsValue();
1462     
1463     ExecState* execCallee = exec - pc[4].u.operand;
1464     
1465     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1466     execCallee->setCallerFrame(exec);
1467     execCallee->uncheckedR(CallFrameSlot::callee) = calleeAsValue;
1468     execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1469     execCallee->setCodeBlock(0);
1470     exec->setCurrentVPC(pc);
1471     
1472     if (!isHostFunction(calleeAsValue, globalFuncEval)) {
1473         throwScope.release();
1474         return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1475     }
1476     
1477     vm.hostCallReturnValue = eval(execCallee);
1478     LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1479 }
1480
1481 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1482 {
1483     LLINT_BEGIN();
1484     LLINT_RETURN(jsStringFromRegisterArray(exec, &LLINT_OP(2), pc[3].u.operand));
1485 }
1486
1487 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1488 {
1489     LLINT_BEGIN();
1490     LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1491 }
1492
1493 LLINT_SLOW_PATH_DECL(slow_path_throw)
1494 {
1495     LLINT_BEGIN();
1496     LLINT_THROW(LLINT_OP_C(1).jsValue());
1497 }
1498
1499 LLINT_SLOW_PATH_DECL(slow_path_handle_traps)
1500 {
1501     LLINT_BEGIN_NO_SET_PC();
1502     ASSERT(vm.needTrapHandling());
1503     vm.handleTraps(exec);
1504     UNUSED_PARAM(pc);
1505     LLINT_RETURN_TWO(throwScope.exception(), exec);
1506 }
1507
1508 LLINT_SLOW_PATH_DECL(slow_path_debug)
1509 {
1510     LLINT_BEGIN();
1511     int debugHookType = pc[1].u.operand;
1512     vm.interpreter->debug(exec, static_cast<DebugHookType>(debugHookType));
1513     
1514     LLINT_END();
1515 }
1516
1517 LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
1518 {
1519     LLINT_BEGIN_NO_SET_PC();
1520     UNUSED_PARAM(throwScope);
1521     genericUnwind(&vm, exec);
1522     LLINT_END_IMPL();
1523 }
1524
1525 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1526 {
1527     LLINT_BEGIN();
1528     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1529     JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1530     GetPutInfo getPutInfo(pc[4].u.operand);
1531
1532     // ModuleVar is always converted to ClosureVar for get_from_scope.
1533     ASSERT(getPutInfo.resolveType() != ModuleVar);
1534
1535     LLINT_RETURN(scope->getPropertySlot(exec, ident, [&] (bool found, PropertySlot& slot) -> JSValue {
1536         if (!found) {
1537             if (getPutInfo.resolveMode() == ThrowIfNotFound)
1538                 return throwException(exec, throwScope, createUndefinedVariableError(exec, ident));
1539             return jsUndefined();
1540         }
1541
1542         JSValue result = JSValue();
1543         if (scope->isGlobalLexicalEnvironment()) {
1544             // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1545             result = slot.getValue(exec, ident);
1546             if (result == jsTDZValue())
1547                 return throwException(exec, throwScope, createTDZError(exec));
1548         }
1549
1550         CommonSlowPaths::tryCacheGetFromScopeGlobal(exec, vm, pc, scope, slot, ident);
1551
1552         if (!result)
1553             return slot.getValue(exec, ident);
1554         return result;
1555     }));
1556 }
1557
1558 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1559 {
1560     LLINT_BEGIN();
1561
1562     CodeBlock* codeBlock = exec->codeBlock();
1563     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1564     JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1565     JSValue value = LLINT_OP_C(3).jsValue();
1566     GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
1567     if (getPutInfo.resolveType() == LocalClosureVar) {
1568         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1569         environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
1570         
1571         // Have to do this *after* the write, because if this puts the set into IsWatched, then we need
1572         // to have already changed the value of the variable. Otherwise we might watch and constant-fold
1573         // to the Undefined value from before the assignment.
1574         if (WatchpointSet* set = pc[5].u.watchpointSet)
1575             set->touch(vm, "Executed op_put_scope<LocalClosureVar>");
1576         LLINT_END();
1577     }
1578
1579     bool hasProperty = scope->hasProperty(exec, ident);
1580     LLINT_CHECK_EXCEPTION();
1581     if (hasProperty
1582         && scope->isGlobalLexicalEnvironment()
1583         && !isInitialization(getPutInfo.initializationMode())) {
1584         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1585         PropertySlot slot(scope, PropertySlot::InternalMethodType::Get);
1586         JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
1587         if (slot.getValue(exec, ident) == jsTDZValue())
1588             LLINT_THROW(createTDZError(exec));
1589     }
1590
1591     if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty)
1592         LLINT_THROW(createUndefinedVariableError(exec, ident));
1593
1594     PutPropertySlot slot(scope, codeBlock->isStrictMode(), PutPropertySlot::UnknownContext, isInitialization(getPutInfo.initializationMode()));
1595     scope->methodTable()->put(scope, exec, ident, value, slot);
1596     
1597     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, getPutInfo, slot, ident);
1598
1599     LLINT_END();
1600 }
1601
1602 LLINT_SLOW_PATH_DECL(slow_path_check_if_exception_is_uncatchable_and_notify_profiler)
1603 {
1604     LLINT_BEGIN();
1605     RELEASE_ASSERT(!!throwScope.exception());
1606
1607     if (isTerminatedExecutionException(vm, throwScope.exception()))
1608         LLINT_RETURN_TWO(pc, bitwise_cast<void*>(static_cast<uintptr_t>(1)));
1609     LLINT_RETURN_TWO(pc, 0);
1610 }
1611
1612 LLINT_SLOW_PATH_DECL(slow_path_log_shadow_chicken_prologue)
1613 {
1614     LLINT_BEGIN();
1615     
1616     JSScope* scope = exec->uncheckedR(pc[1].u.operand).Register::scope();
1617     vm.shadowChicken().log(vm, exec, ShadowChicken::Packet::prologue(exec->jsCallee(), exec, exec->callerFrame(), scope));
1618     
1619     LLINT_END();
1620 }
1621
1622 LLINT_SLOW_PATH_DECL(slow_path_log_shadow_chicken_tail)
1623 {
1624     LLINT_BEGIN();
1625
1626     JSValue thisValue = LLINT_OP(1).jsValue();
1627     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1628     
1629 #if USE(JSVALUE64)
1630     CallSiteIndex callSiteIndex(exec->codeBlock()->bytecodeOffset(pc));
1631 #else
1632     CallSiteIndex callSiteIndex(pc);
1633 #endif
1634     vm.shadowChicken().log(vm, exec, ShadowChicken::Packet::tail(exec, thisValue, scope, exec->codeBlock(), callSiteIndex));
1635     
1636     LLINT_END();
1637 }
1638
1639 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
1640 {
1641     ExecState* exec = vm->topCallFrame;
1642     auto scope = DECLARE_THROW_SCOPE(*vm);
1643
1644     if (!exec)
1645         exec = protoFrame->callee()->globalObject()->globalExec();
1646     throwStackOverflowError(exec, scope);
1647     return encodeResult(0, 0);
1648 }
1649
1650 #if !ENABLE(JIT)
1651 extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM* vm, Register* newTopOfStack)
1652 {
1653     bool success = vm->ensureStackCapacityFor(newTopOfStack);
1654     return encodeResult(reinterpret_cast<void*>(success), 0);
1655 }
1656 #endif
1657
1658 extern "C" void llint_write_barrier_slow(ExecState* exec, JSCell* cell)
1659 {
1660     VM& vm = exec->vm();
1661     vm.heap.writeBarrier(cell);
1662 }
1663
1664 extern "C" NO_RETURN_DUE_TO_CRASH void llint_crash()
1665 {
1666     CRASH();
1667 }
1668
1669 #if ENABLE(LLINT_STATS)
1670
1671 LLINT_SLOW_PATH_DECL(count_opcode)
1672 {
1673     OpcodeID opcodeID = Interpreter::getOpcodeID(pc[0].u.opcode);
1674     Data::opcodeStats(opcodeID).count++;
1675     LLINT_END_IMPL();
1676 }
1677
1678 LLINT_SLOW_PATH_DECL(count_opcode_slow_path)
1679 {
1680     OpcodeID opcodeID = Interpreter::getOpcodeID(pc[0].u.opcode);
1681     Data::opcodeStats(opcodeID).slowPathCount++;
1682     LLINT_END_IMPL();
1683 }
1684
1685 #endif // ENABLE(LLINT_STATS)
1686
1687 } } // namespace JSC::LLInt