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