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