Block scoped variables should be visible across scripts
[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)
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)) {
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)) {
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))
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     CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
489     pc = returnToThrowForThrownException(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         if (!structure->isUncacheableDictionary()
574             && !structure->typeInfo().prohibitsPropertyCaching()
575             && !structure->typeInfo().newImpurePropertyFiresWatchpoints()) {
576             ConcurrentJITLocker locker(codeBlock->m_lock);
577
578             pc[4].u.structure.set(
579                 vm, codeBlock->ownerExecutable(), structure);
580             if (isInlineOffset(slot.cachedOffset())) {
581                 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
582                 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
583             } else {
584                 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_out_of_line);
585                 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
586             }
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.operand)
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         JSCell* baseCell = baseValue.asCell();
632         Structure* structure = baseCell->structure();
633         
634         if (!structure->isUncacheableDictionary()
635             && !structure->typeInfo().prohibitsPropertyCaching()
636             && baseCell == slot.base()) {
637             
638             if (slot.type() == PutPropertySlot::NewProperty) {
639                 GCSafeConcurrentJITLocker locker(codeBlock->m_lock, vm.heap);
640             
641                 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
642                     ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
643                     
644                     // This is needed because some of the methods we call
645                     // below may GC.
646                     pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
647
648                     if (normalizePrototypeChain(exec, structure) != InvalidPrototypeChain) {
649                         ASSERT(structure->previousID()->isObject());
650                         pc[4].u.structure.set(
651                             vm, codeBlock->ownerExecutable(), structure->previousID());
652                         if (isInlineOffset(slot.cachedOffset()))
653                             pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
654                         else
655                             pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
656                         pc[6].u.structure.set(
657                             vm, codeBlock->ownerExecutable(), structure);
658                         StructureChain* chain = structure->prototypeChain(exec);
659                         ASSERT(chain);
660                         pc[7].u.structureChain.set(
661                             vm, codeBlock->ownerExecutable(), chain);
662                     
663                         if (pc[8].u.operand) {
664                             if (isInlineOffset(slot.cachedOffset()))
665                                 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct);
666                             else
667                                 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct_out_of_line);
668                         } else {
669                             if (isInlineOffset(slot.cachedOffset()))
670                                 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal);
671                             else
672                                 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal_out_of_line);
673                         }
674                     }
675                 }
676             } else {
677                 structure->didCachePropertyReplacement(vm, slot.cachedOffset());
678                 pc[4].u.structure.set(
679                     vm, codeBlock->ownerExecutable(), structure);
680                 if (isInlineOffset(slot.cachedOffset())) {
681                     pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
682                     pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
683                 } else {
684                     pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_out_of_line);
685                     pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
686                 }
687             }
688         }
689     }
690     
691     LLINT_END();
692 }
693
694 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
695 {
696     LLINT_BEGIN();
697     CodeBlock* codeBlock = exec->codeBlock();
698     JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
699     bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
700     LLINT_CHECK_EXCEPTION();
701     if (!couldDelete && codeBlock->isStrictMode())
702         LLINT_THROW(createTypeError(exec, "Unable to delete property."));
703     LLINT_RETURN(jsBoolean(couldDelete));
704 }
705
706 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
707 {
708     if (LIKELY(baseValue.isCell() && subscript.isString())) {
709         VM& vm = exec->vm();
710         Structure& structure = *baseValue.asCell()->structure(vm);
711         if (JSCell::canUseFastGetOwnProperty(structure)) {
712             if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
713                 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
714                     return result;
715             }
716         }
717     }
718     
719     if (subscript.isUInt32()) {
720         uint32_t i = subscript.asUInt32();
721         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
722             return asString(baseValue)->getIndex(exec, i);
723         
724         return baseValue.get(exec, i);
725     }
726
727     baseValue.requireObjectCoercible(exec);
728     if (exec->hadException())
729         return jsUndefined();
730     auto property = subscript.toPropertyKey(exec);
731     if (exec->hadException())
732         return jsUndefined();
733     return baseValue.get(exec, property);
734 }
735
736 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
737 {
738     LLINT_BEGIN();
739     LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
740 }
741
742 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
743 {
744     LLINT_BEGIN();
745     
746     JSValue baseValue = LLINT_OP_C(1).jsValue();
747     JSValue subscript = LLINT_OP_C(2).jsValue();
748     JSValue value = LLINT_OP_C(3).jsValue();
749     
750     if (LIKELY(subscript.isUInt32())) {
751         uint32_t i = subscript.asUInt32();
752         if (baseValue.isObject()) {
753             JSObject* object = asObject(baseValue);
754             if (object->canSetIndexQuickly(i))
755                 object->setIndexQuickly(vm, i, value);
756             else
757                 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
758             LLINT_END();
759         }
760         baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
761         LLINT_END();
762     }
763
764     auto property = subscript.toPropertyKey(exec);
765     LLINT_CHECK_EXCEPTION();
766     PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
767     baseValue.put(exec, property, value, slot);
768     LLINT_END();
769 }
770
771 LLINT_SLOW_PATH_DECL(slow_path_put_by_val_direct)
772 {
773     LLINT_BEGIN();
774     
775     JSValue baseValue = LLINT_OP_C(1).jsValue();
776     JSValue subscript = LLINT_OP_C(2).jsValue();
777     JSValue value = LLINT_OP_C(3).jsValue();
778     RELEASE_ASSERT(baseValue.isObject());
779     JSObject* baseObject = asObject(baseValue);
780     bool isStrictMode = exec->codeBlock()->isStrictMode();
781     if (LIKELY(subscript.isUInt32())) {
782         // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
783         ASSERT(isIndex(subscript.asUInt32()));
784         baseObject->putDirectIndex(exec, subscript.asUInt32(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
785         LLINT_END();
786     }
787
788     if (subscript.isDouble()) {
789         double subscriptAsDouble = subscript.asDouble();
790         uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
791         if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
792             baseObject->putDirectIndex(exec, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
793             LLINT_END();
794         }
795     }
796
797     // Don't put to an object if toString threw an exception.
798     auto property = subscript.toPropertyKey(exec);
799     if (exec->vm().exception())
800         LLINT_END();
801
802     if (Optional<uint32_t> index = parseIndex(property))
803         baseObject->putDirectIndex(exec, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
804     else {
805         PutPropertySlot slot(baseObject, isStrictMode);
806         baseObject->putDirect(exec->vm(), property, value, slot);
807     }
808     LLINT_END();
809 }
810
811 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
812 {
813     LLINT_BEGIN();
814     JSValue baseValue = LLINT_OP_C(2).jsValue();
815     JSObject* baseObject = baseValue.toObject(exec);
816     
817     JSValue subscript = LLINT_OP_C(3).jsValue();
818     
819     bool couldDelete;
820     
821     uint32_t i;
822     if (subscript.getUInt32(i))
823         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
824     else {
825         LLINT_CHECK_EXCEPTION();
826         auto property = subscript.toPropertyKey(exec);
827         LLINT_CHECK_EXCEPTION();
828         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
829     }
830     
831     if (!couldDelete && exec->codeBlock()->isStrictMode())
832         LLINT_THROW(createTypeError(exec, "Unable to delete property."));
833     
834     LLINT_RETURN(jsBoolean(couldDelete));
835 }
836
837 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
838 {
839     LLINT_BEGIN();
840     JSValue arrayValue = LLINT_OP_C(1).jsValue();
841     ASSERT(isJSArray(arrayValue));
842     asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
843     LLINT_END();
844 }
845
846 LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
847 {
848     LLINT_BEGIN();
849     ASSERT(LLINT_OP(1).jsValue().isObject());
850     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
851
852     unsigned options = pc[3].u.operand;
853
854     JSValue getter = LLINT_OP(4).jsValue();
855     ASSERT(getter.isObject());
856
857     baseObj->putGetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(getter), options);
858     LLINT_END();
859 }
860
861 LLINT_SLOW_PATH_DECL(slow_path_put_setter_by_id)
862 {
863     LLINT_BEGIN();
864     ASSERT(LLINT_OP(1).jsValue().isObject());
865     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
866
867     unsigned options = pc[3].u.operand;
868
869     JSValue setter = LLINT_OP(4).jsValue();
870     ASSERT(setter.isObject());
871
872     baseObj->putSetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(setter), options);
873     LLINT_END();
874 }
875
876 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
877 {
878     LLINT_BEGIN();
879     ASSERT(LLINT_OP(1).jsValue().isObject());
880     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
881     
882     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
883     LLINT_CHECK_EXCEPTION();
884
885     JSValue getter = LLINT_OP(4).jsValue();
886     JSValue setter = LLINT_OP(5).jsValue();
887     ASSERT(getter.isObject() || getter.isUndefined());
888     ASSERT(setter.isObject() || setter.isUndefined());
889     ASSERT(getter.isObject() || setter.isObject());
890     
891     if (!getter.isUndefined())
892         accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
893     if (!setter.isUndefined())
894         accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
895     baseObj->putDirectAccessor(
896         exec,
897         exec->codeBlock()->identifier(pc[2].u.operand),
898         accessor, pc[3].u.operand);
899     LLINT_END();
900 }
901
902 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
903 {
904     LLINT_BEGIN();
905     LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
906 }
907
908 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
909 {
910     LLINT_BEGIN();
911     LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
912 }
913
914 LLINT_SLOW_PATH_DECL(slow_path_jless)
915 {
916     LLINT_BEGIN();
917     LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
918 }
919
920 LLINT_SLOW_PATH_DECL(slow_path_jnless)
921 {
922     LLINT_BEGIN();
923     LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
924 }
925
926 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
927 {
928     LLINT_BEGIN();
929     LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
930 }
931
932 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
933 {
934     LLINT_BEGIN();
935     LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
936 }
937
938 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
939 {
940     LLINT_BEGIN();
941     LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
942 }
943
944 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
945 {
946     LLINT_BEGIN();
947     LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
948 }
949
950 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
951 {
952     LLINT_BEGIN();
953     LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
954 }
955
956 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
957 {
958     LLINT_BEGIN();
959     LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
960 }
961
962 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
963 {
964     LLINT_BEGIN();
965     JSValue scrutinee = LLINT_OP_C(3).jsValue();
966     ASSERT(scrutinee.isDouble());
967     double value = scrutinee.asDouble();
968     int32_t intValue = static_cast<int32_t>(value);
969     int defaultOffset = pc[2].u.operand;
970     if (value == intValue) {
971         CodeBlock* codeBlock = exec->codeBlock();
972         pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
973     } else
974         pc += defaultOffset;
975     LLINT_END();
976 }
977
978 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
979 {
980     LLINT_BEGIN();
981     JSValue scrutinee = LLINT_OP_C(3).jsValue();
982     ASSERT(scrutinee.isString());
983     JSString* string = asString(scrutinee);
984     ASSERT(string->length() == 1);
985     int defaultOffset = pc[2].u.operand;
986     StringImpl* impl = string->value(exec).impl();
987     CodeBlock* codeBlock = exec->codeBlock();
988     pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
989     LLINT_END();
990 }
991
992 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
993 {
994     LLINT_BEGIN();
995     JSValue scrutinee = LLINT_OP_C(3).jsValue();
996     int defaultOffset = pc[2].u.operand;
997     if (!scrutinee.isString())
998         pc += defaultOffset;
999     else {
1000         CodeBlock* codeBlock = exec->codeBlock();
1001         pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1002     }
1003     LLINT_END();
1004 }
1005
1006 LLINT_SLOW_PATH_DECL(slow_path_new_func)
1007 {
1008     LLINT_BEGIN();
1009     CodeBlock* codeBlock = exec->codeBlock();
1010     ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation());
1011     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1012 #if LLINT_SLOW_PATH_TRACING
1013     dataLogF("Creating function!\n");
1014 #endif
1015     LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
1016 }
1017
1018 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1019 {
1020     LLINT_BEGIN();
1021     
1022     CodeBlock* codeBlock = exec->codeBlock();
1023     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1024     FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
1025     
1026     LLINT_RETURN(JSFunction::create(vm, executable, scope));
1027 }
1028
1029 LLINT_SLOW_PATH_DECL(slow_path_new_arrow_func_exp)
1030 {
1031     LLINT_BEGIN();
1032
1033     JSValue thisValue = LLINT_OP_C(4).jsValue();
1034     CodeBlock* codeBlock = exec->codeBlock();
1035     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1036     FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
1037     
1038     LLINT_RETURN(JSArrowFunction::create(vm, executable, scope, thisValue));
1039 }
1040
1041 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1042 {
1043     UNUSED_PARAM(pc);
1044
1045 #if LLINT_SLOW_PATH_TRACING
1046     dataLog("Performing host call.\n");
1047 #endif
1048     
1049     ExecState* exec = execCallee->callerFrame();
1050     VM& vm = exec->vm();
1051
1052     execCallee->setCodeBlock(0);
1053     execCallee->clearReturnPC();
1054
1055     if (kind == CodeForCall) {
1056         CallData callData;
1057         CallType callType = getCallData(callee, callData);
1058     
1059         ASSERT(callType != CallTypeJS);
1060     
1061         if (callType == CallTypeHost) {
1062             NativeCallFrameTracer tracer(&vm, execCallee);
1063             execCallee->setCallee(asObject(callee));
1064             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1065             
1066             LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1067         }
1068         
1069 #if LLINT_SLOW_PATH_TRACING
1070         dataLog("Call callee is not a function: ", callee, "\n");
1071 #endif
1072
1073         ASSERT(callType == CallTypeNone);
1074         LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
1075     }
1076
1077     ASSERT(kind == CodeForConstruct);
1078     
1079     ConstructData constructData;
1080     ConstructType constructType = getConstructData(callee, constructData);
1081     
1082     ASSERT(constructType != ConstructTypeJS);
1083     
1084     if (constructType == ConstructTypeHost) {
1085         NativeCallFrameTracer tracer(&vm, execCallee);
1086         execCallee->setCallee(asObject(callee));
1087         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1088
1089         LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1090     }
1091     
1092 #if LLINT_SLOW_PATH_TRACING
1093     dataLog("Constructor callee is not a function: ", callee, "\n");
1094 #endif
1095
1096     ASSERT(constructType == ConstructTypeNone);
1097     LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1098 }
1099
1100 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1101 {
1102     ExecState* exec = execCallee->callerFrame();
1103
1104 #if LLINT_SLOW_PATH_TRACING
1105     dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
1106 #endif
1107     
1108     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1109     if (!calleeAsFunctionCell)
1110         return handleHostCall(execCallee, pc, calleeAsValue, kind);
1111     
1112     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1113     JSScope* scope = callee->scopeUnchecked();
1114     VM& vm = *scope->vm();
1115     ExecutableBase* executable = callee->executable();
1116
1117     MacroAssemblerCodePtr codePtr;
1118     CodeBlock* codeBlock = 0;
1119     bool isWebAssemblyExecutable = false;
1120 #if ENABLE(WEBASSEMBLY)
1121     isWebAssemblyExecutable = executable->isWebAssemblyExecutable();
1122 #endif
1123
1124     if (executable->isHostFunction()) {
1125         codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
1126     } else if (!isWebAssemblyExecutable) {
1127         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1128
1129         if (!isCall(kind) && functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
1130             LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1131
1132         JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, scope, kind);
1133         if (error)
1134             LLINT_CALL_THROW(exec, error);
1135         codeBlock = functionExecutable->codeBlockFor(kind);
1136         ASSERT(codeBlock);
1137         ArityCheckMode arity;
1138         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1139             arity = MustCheckArity;
1140         else
1141             arity = ArityCheckNotRequired;
1142         codePtr = functionExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
1143     } else {
1144 #if ENABLE(WEBASSEMBLY)
1145         WebAssemblyExecutable* webAssemblyExecutable = static_cast<WebAssemblyExecutable*>(executable);
1146         webAssemblyExecutable->prepareForExecution(execCallee);
1147         codeBlock = webAssemblyExecutable->codeBlockForCall();
1148         ASSERT(codeBlock);
1149         ArityCheckMode arity;
1150         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1151             arity = MustCheckArity;
1152         else
1153             arity = ArityCheckNotRequired;
1154         codePtr = webAssemblyExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
1155 #endif
1156     }
1157     
1158     ASSERT(!!codePtr);
1159     
1160     if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1161         CodeBlock* callerCodeBlock = exec->codeBlock();
1162
1163         ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1164         
1165         if (callLinkInfo->isOnList())
1166             callLinkInfo->remove();
1167         callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1168         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1169         callLinkInfo->machineCodeTarget = codePtr;
1170         if (codeBlock)
1171             codeBlock->linkIncomingCall(exec, callLinkInfo);
1172     }
1173
1174     LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
1175 }
1176
1177 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1178 {
1179     // This needs to:
1180     // - Set up a call frame.
1181     // - Figure out what to call and compile it if necessary.
1182     // - If possible, link the call's inline cache.
1183     // - Return a tuple of machine code address to call and the new call frame.
1184     
1185     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1186     
1187     ExecState* execCallee = exec - pc[4].u.operand;
1188     
1189     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1190     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1191     execCallee->setCallerFrame(exec);
1192     
1193     ASSERT(pc[5].u.callLinkInfo);
1194     return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1195 }
1196
1197 LLINT_SLOW_PATH_DECL(slow_path_call)
1198 {
1199     LLINT_BEGIN_NO_SET_PC();
1200     return genericCall(exec, pc, CodeForCall);
1201 }
1202
1203 LLINT_SLOW_PATH_DECL(slow_path_construct)
1204 {
1205     LLINT_BEGIN_NO_SET_PC();
1206     return genericCall(exec, pc, CodeForConstruct);
1207 }
1208
1209 LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_varargs)
1210 {
1211     LLINT_BEGIN();
1212     // This needs to:
1213     // - Set up a call frame while respecting the variable arguments.
1214     
1215     unsigned numUsedStackSlots = -pc[5].u.operand;
1216     unsigned length = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
1217         LLINT_OP_C(4).jsValue(), numUsedStackSlots, pc[6].u.operand);
1218     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1219     
1220     ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, length + 1);
1221     vm.varargsLength = length;
1222     vm.newCallFrameReturnValue = execCallee;
1223
1224     LLINT_RETURN_CALLEE_FRAME(execCallee);
1225 }
1226
1227 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1228 {
1229     LLINT_BEGIN_NO_SET_PC();
1230     // This needs to:
1231     // - Figure out what to call and compile it if necessary.
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 = vm.newCallFrameReturnValue;
1237
1238     setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
1239     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1240     
1241     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1242     execCallee->setCallerFrame(exec);
1243     exec->setCurrentVPC(pc);
1244     
1245     return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1246 }
1247     
1248 LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
1249 {
1250     LLINT_BEGIN_NO_SET_PC();
1251     // This needs to:
1252     // - Figure out what to call and compile it if necessary.
1253     // - Return a tuple of machine code address to call and the new call frame.
1254     
1255     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1256     
1257     ExecState* execCallee = vm.newCallFrameReturnValue;
1258     
1259     setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
1260     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1261     
1262     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1263     execCallee->setCallerFrame(exec);
1264     exec->setCurrentVPC(pc);
1265     
1266     return setUpCall(execCallee, pc, CodeForConstruct, calleeAsValue);
1267 }
1268     
1269 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1270 {
1271     LLINT_BEGIN_NO_SET_PC();
1272     JSValue calleeAsValue = LLINT_OP(2).jsValue();
1273     
1274     ExecState* execCallee = exec - pc[4].u.operand;
1275     
1276     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1277     execCallee->setCallerFrame(exec);
1278     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1279     execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1280     execCallee->setCodeBlock(0);
1281     exec->setCurrentVPC(pc);
1282     
1283     if (!isHostFunction(calleeAsValue, globalFuncEval))
1284         return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1285     
1286     vm.hostCallReturnValue = eval(execCallee);
1287     LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1288 }
1289
1290 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1291 {
1292     LLINT_BEGIN();
1293     LLINT_RETURN(jsStringFromRegisterArray(exec, &LLINT_OP(2), pc[3].u.operand));
1294 }
1295
1296 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1297 {
1298     LLINT_BEGIN();
1299     LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1300 }
1301
1302 LLINT_SLOW_PATH_DECL(slow_path_throw)
1303 {
1304     LLINT_BEGIN();
1305     LLINT_THROW(LLINT_OP_C(1).jsValue());
1306 }
1307
1308 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1309 {
1310     LLINT_BEGIN();
1311     JSValue errorMessageValue = LLINT_OP_C(1).jsValue();
1312     RELEASE_ASSERT(errorMessageValue.isString());
1313     String errorMessage = asString(errorMessageValue)->value(exec);
1314     if (pc[2].u.operand)
1315         LLINT_THROW(createReferenceError(exec, errorMessage));
1316     else
1317         LLINT_THROW(createTypeError(exec, errorMessage));
1318 }
1319
1320 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1321 {
1322     LLINT_BEGIN_NO_SET_PC();
1323     ASSERT(vm.watchdog);
1324     if (UNLIKELY(vm.shouldTriggerTermination(exec)))
1325         LLINT_THROW(createTerminatedExecutionException(&vm));
1326     LLINT_RETURN_TWO(0, exec);
1327 }
1328
1329 LLINT_SLOW_PATH_DECL(slow_path_debug)
1330 {
1331     LLINT_BEGIN();
1332     int debugHookID = pc[1].u.operand;
1333     vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID));
1334     
1335     LLINT_END();
1336 }
1337
1338 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1339 {
1340     LLINT_BEGIN();
1341     if (LegacyProfiler* profiler = vm.enabledProfiler())
1342         profiler->willExecute(exec, LLINT_OP(1).jsValue());
1343     LLINT_END();
1344 }
1345
1346 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1347 {
1348     LLINT_BEGIN();
1349     if (LegacyProfiler* profiler = vm.enabledProfiler())
1350         profiler->didExecute(exec, LLINT_OP(1).jsValue());
1351     LLINT_END();
1352 }
1353
1354 LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
1355 {
1356     LLINT_BEGIN_NO_SET_PC();
1357     genericUnwind(&vm, exec);
1358     LLINT_END_IMPL();
1359 }
1360
1361 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1362 {
1363     LLINT_BEGIN();
1364
1365     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1366     JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1367     GetPutInfo getPutInfo(pc[4].u.operand);
1368
1369     PropertySlot slot(scope);
1370     if (!scope->getPropertySlot(exec, ident, slot)) {
1371         if (getPutInfo.resolveMode() == ThrowIfNotFound)
1372             LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1373         LLINT_RETURN(jsUndefined());
1374     }
1375
1376     JSValue result = JSValue();
1377     if (jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)) {
1378         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1379         result = slot.getValue(exec, ident);
1380         if (result == jsTDZValue())
1381             LLINT_THROW(createTDZError(exec));
1382     }
1383
1384     CommonSlowPaths::tryCacheGetFromScopeGlobal(exec, vm, pc, scope, slot, ident);
1385
1386     if (!result)
1387         result = slot.getValue(exec, ident);
1388     LLINT_RETURN(result);
1389 }
1390
1391 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1392 {
1393     LLINT_BEGIN();
1394
1395     CodeBlock* codeBlock = exec->codeBlock();
1396     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1397     JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1398     JSValue value = LLINT_OP_C(3).jsValue();
1399     GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
1400     if (getPutInfo.resolveType() == LocalClosureVar) {
1401         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1402         environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
1403         
1404         // Have to do this *after* the write, because if this puts the set into IsWatched, then we need
1405         // to have already changed the value of the variable. Otherwise we might watch and constant-fold
1406         // to the Undefined value from before the assignment.
1407         if (WatchpointSet* set = pc[5].u.watchpointSet)
1408             set->touch("Executed op_put_scope<LocalClosureVar>");
1409         LLINT_END();
1410     }
1411
1412     bool hasProperty = scope->hasProperty(exec, ident);
1413     if (hasProperty
1414         && jsDynamicCast<JSGlobalLexicalEnvironment*>(scope)
1415         && getPutInfo.initializationMode() != Initialization) {
1416         // When we can't statically prove we need a TDZ check, we must perform the check on the slow path.
1417         PropertySlot slot(scope);
1418         JSGlobalLexicalEnvironment::getOwnPropertySlot(scope, exec, ident, slot);
1419         if (slot.getValue(exec, ident) == jsTDZValue())
1420             LLINT_THROW(createTDZError(exec));
1421     }
1422
1423     if (getPutInfo.resolveMode() == ThrowIfNotFound && !hasProperty)
1424         LLINT_THROW(createUndefinedVariableError(exec, ident));
1425
1426     PutPropertySlot slot(scope, codeBlock->isStrictMode(), PutPropertySlot::UnknownContext, getPutInfo.initializationMode() == Initialization);
1427     scope->methodTable()->put(scope, exec, ident, value, slot);
1428     
1429     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, getPutInfo, slot, ident);
1430
1431     LLINT_END();
1432 }
1433
1434 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
1435 {
1436     ExecState* exec = vm->topCallFrame;
1437     if (!exec)
1438         exec = protoFrame->callee()->globalObject()->globalExec();
1439     throwStackOverflowError(exec);
1440     return encodeResult(0, 0);
1441 }
1442
1443 #if !ENABLE(JIT)
1444 extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM* vm, Register* newTopOfStack)
1445 {
1446     bool success = vm->interpreter->stack().ensureCapacityFor(newTopOfStack);
1447     return encodeResult(reinterpret_cast<void*>(success), 0);
1448 }
1449 #endif
1450
1451 extern "C" void llint_write_barrier_slow(ExecState* exec, JSCell* cell)
1452 {
1453     VM& vm = exec->vm();
1454     vm.heap.writeBarrier(cell);
1455 }
1456
1457 extern "C" NO_RETURN_DUE_TO_CRASH void llint_crash()
1458 {
1459     CRASH();
1460 }
1461
1462 } } // namespace JSC::LLInt