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