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