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