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