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