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