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