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