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