85bac2603a7b2157b9559b2fe185a677652d2d5e
[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     if (LIKELY(subscript.isUInt32())) {
823         uint32_t i = subscript.asUInt32();
824         baseObject->putDirectIndex(exec, i, value);
825     } else if (isName(subscript)) {
826         PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
827         baseObject->putDirect(exec->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
828     } else {
829         Identifier property = subscript.toString(exec)->toIdentifier(exec);
830         if (!exec->vm().exception()) { // Don't put to an object if toString threw an exception.
831             PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
832             baseObject->putDirect(exec->vm(), property, value, slot);
833         }
834     }
835     LLINT_END();
836 }
837
838 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
839 {
840     LLINT_BEGIN();
841     JSValue baseValue = LLINT_OP_C(2).jsValue();
842     JSObject* baseObject = baseValue.toObject(exec);
843     
844     JSValue subscript = LLINT_OP_C(3).jsValue();
845     
846     bool couldDelete;
847     
848     uint32_t i;
849     if (subscript.getUInt32(i))
850         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
851     else if (isName(subscript))
852         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
853     else {
854         LLINT_CHECK_EXCEPTION();
855         Identifier property = subscript.toString(exec)->toIdentifier(exec);
856         LLINT_CHECK_EXCEPTION();
857         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
858     }
859     
860     if (!couldDelete && exec->codeBlock()->isStrictMode())
861         LLINT_THROW(createTypeError(exec, "Unable to delete property."));
862     
863     LLINT_RETURN(jsBoolean(couldDelete));
864 }
865
866 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
867 {
868     LLINT_BEGIN();
869     JSValue arrayValue = LLINT_OP_C(1).jsValue();
870     ASSERT(isJSArray(arrayValue));
871     asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
872     LLINT_END();
873 }
874
875 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
876 {
877     LLINT_BEGIN();
878     ASSERT(LLINT_OP(1).jsValue().isObject());
879     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
880     
881     GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
882     LLINT_CHECK_EXCEPTION();
883     
884     JSValue getter = LLINT_OP(3).jsValue();
885     JSValue setter = LLINT_OP(4).jsValue();
886     ASSERT(getter.isObject() || getter.isUndefined());
887     ASSERT(setter.isObject() || setter.isUndefined());
888     ASSERT(getter.isObject() || setter.isObject());
889     
890     if (!getter.isUndefined())
891         accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
892     if (!setter.isUndefined())
893         accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
894     baseObj->putDirectAccessor(
895         exec,
896         exec->codeBlock()->identifier(pc[2].u.operand),
897         accessor, Accessor);
898     LLINT_END();
899 }
900
901 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
902 {
903     LLINT_BEGIN();
904     LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
905 }
906
907 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
908 {
909     LLINT_BEGIN();
910     LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
911 }
912
913 LLINT_SLOW_PATH_DECL(slow_path_jless)
914 {
915     LLINT_BEGIN();
916     LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
917 }
918
919 LLINT_SLOW_PATH_DECL(slow_path_jnless)
920 {
921     LLINT_BEGIN();
922     LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
923 }
924
925 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
926 {
927     LLINT_BEGIN();
928     LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
929 }
930
931 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
932 {
933     LLINT_BEGIN();
934     LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
935 }
936
937 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
938 {
939     LLINT_BEGIN();
940     LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
941 }
942
943 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
944 {
945     LLINT_BEGIN();
946     LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
947 }
948
949 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
950 {
951     LLINT_BEGIN();
952     LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
953 }
954
955 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
956 {
957     LLINT_BEGIN();
958     LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
959 }
960
961 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
962 {
963     LLINT_BEGIN();
964     JSValue scrutinee = LLINT_OP_C(3).jsValue();
965     ASSERT(scrutinee.isDouble());
966     double value = scrutinee.asDouble();
967     int32_t intValue = static_cast<int32_t>(value);
968     int defaultOffset = pc[2].u.operand;
969     if (value == intValue) {
970         CodeBlock* codeBlock = exec->codeBlock();
971         pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
972     } else
973         pc += defaultOffset;
974     LLINT_END();
975 }
976
977 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
978 {
979     LLINT_BEGIN();
980     JSValue scrutinee = LLINT_OP_C(3).jsValue();
981     ASSERT(scrutinee.isString());
982     JSString* string = asString(scrutinee);
983     ASSERT(string->length() == 1);
984     int defaultOffset = pc[2].u.operand;
985     StringImpl* impl = string->value(exec).impl();
986     CodeBlock* codeBlock = exec->codeBlock();
987     pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
988     LLINT_END();
989 }
990
991 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
992 {
993     LLINT_BEGIN();
994     JSValue scrutinee = LLINT_OP_C(3).jsValue();
995     int defaultOffset = pc[2].u.operand;
996     if (!scrutinee.isString())
997         pc += defaultOffset;
998     else {
999         CodeBlock* codeBlock = exec->codeBlock();
1000         pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1001     }
1002     LLINT_END();
1003 }
1004
1005 LLINT_SLOW_PATH_DECL(slow_path_new_func)
1006 {
1007     LLINT_BEGIN();
1008     CodeBlock* codeBlock = exec->codeBlock();
1009     ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation());
1010     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1011 #if LLINT_SLOW_PATH_TRACING
1012     dataLogF("Creating function!\n");
1013 #endif
1014     LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
1015 }
1016
1017 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1018 {
1019     LLINT_BEGIN();
1020     CodeBlock* codeBlock = exec->codeBlock();
1021     JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1022     FunctionExecutable* function = codeBlock->functionExpr(pc[3].u.operand);
1023     JSFunction* func = JSFunction::create(vm, function, scope);
1024     
1025     LLINT_RETURN(func);
1026 }
1027
1028 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1029 {
1030     UNUSED_PARAM(pc);
1031
1032 #if LLINT_SLOW_PATH_TRACING
1033     dataLog("Performing host call.\n");
1034 #endif
1035     
1036     ExecState* exec = execCallee->callerFrame();
1037     VM& vm = exec->vm();
1038
1039     execCallee->setCodeBlock(0);
1040     execCallee->clearReturnPC();
1041
1042     if (kind == CodeForCall) {
1043         CallData callData;
1044         CallType callType = getCallData(callee, callData);
1045     
1046         ASSERT(callType != CallTypeJS);
1047     
1048         if (callType == CallTypeHost) {
1049             NativeCallFrameTracer tracer(&vm, execCallee);
1050             execCallee->setCallee(asObject(callee));
1051             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1052             
1053             LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1054         }
1055         
1056 #if LLINT_SLOW_PATH_TRACING
1057         dataLog("Call callee is not a function: ", callee, "\n");
1058 #endif
1059
1060         ASSERT(callType == CallTypeNone);
1061         LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
1062     }
1063
1064     ASSERT(kind == CodeForConstruct);
1065     
1066     ConstructData constructData;
1067     ConstructType constructType = getConstructData(callee, constructData);
1068     
1069     ASSERT(constructType != ConstructTypeJS);
1070     
1071     if (constructType == ConstructTypeHost) {
1072         NativeCallFrameTracer tracer(&vm, execCallee);
1073         execCallee->setCallee(asObject(callee));
1074         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1075
1076         LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1077     }
1078     
1079 #if LLINT_SLOW_PATH_TRACING
1080     dataLog("Constructor callee is not a function: ", callee, "\n");
1081 #endif
1082
1083     ASSERT(constructType == ConstructTypeNone);
1084     LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1085 }
1086
1087 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1088 {
1089     ExecState* exec = execCallee->callerFrame();
1090
1091 #if LLINT_SLOW_PATH_TRACING
1092     dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
1093 #endif
1094     
1095     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1096     if (!calleeAsFunctionCell)
1097         return handleHostCall(execCallee, pc, calleeAsValue, kind);
1098     
1099     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1100     JSScope* scope = callee->scopeUnchecked();
1101     VM& vm = *scope->vm();
1102     ExecutableBase* executable = callee->executable();
1103     
1104     MacroAssemblerCodePtr codePtr;
1105     CodeBlock* codeBlock = 0;
1106     if (executable->isHostFunction())
1107         codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
1108     else {
1109         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1110         JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, &scope, kind);
1111         if (error)
1112             LLINT_CALL_THROW(exec, error);
1113         codeBlock = functionExecutable->codeBlockFor(kind);
1114         ASSERT(codeBlock);
1115         ArityCheckMode arity;
1116         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1117             arity = MustCheckArity;
1118         else
1119             arity = ArityCheckNotRequired;
1120         codePtr = functionExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
1121     }
1122     
1123     ASSERT(!!codePtr);
1124     
1125     if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1126         CodeBlock* callerCodeBlock = exec->codeBlock();
1127
1128         ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1129         
1130         if (callLinkInfo->isOnList())
1131             callLinkInfo->remove();
1132         callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1133         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1134         callLinkInfo->machineCodeTarget = codePtr;
1135         if (codeBlock)
1136             codeBlock->linkIncomingCall(exec, callLinkInfo);
1137     }
1138
1139     LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
1140 }
1141
1142 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1143 {
1144     // This needs to:
1145     // - Set up a call frame.
1146     // - Figure out what to call and compile it if necessary.
1147     // - If possible, link the call's inline cache.
1148     // - Return a tuple of machine code address to call and the new call frame.
1149     
1150     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1151     
1152     ExecState* execCallee = exec - pc[4].u.operand;
1153     
1154     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1155     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1156     execCallee->setCallerFrame(exec);
1157     
1158     ASSERT(pc[5].u.callLinkInfo);
1159     return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1160 }
1161
1162 LLINT_SLOW_PATH_DECL(slow_path_call)
1163 {
1164     LLINT_BEGIN_NO_SET_PC();
1165     return genericCall(exec, pc, CodeForCall);
1166 }
1167
1168 LLINT_SLOW_PATH_DECL(slow_path_construct)
1169 {
1170     LLINT_BEGIN_NO_SET_PC();
1171     return genericCall(exec, pc, CodeForConstruct);
1172 }
1173
1174 LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_varargs)
1175 {
1176     LLINT_BEGIN();
1177     // This needs to:
1178     // - Set up a call frame while respecting the variable arguments.
1179     
1180     ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
1181         LLINT_OP_C(4).jsValue(), pc[5].u.operand, pc[6].u.operand);
1182     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1183     
1184     vm.newCallFrameReturnValue = execCallee;
1185
1186     LLINT_RETURN_CALLEE_FRAME(execCallee);
1187 }
1188
1189 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1190 {
1191     LLINT_BEGIN_NO_SET_PC();
1192     // This needs to:
1193     // - Figure out what to call and compile it if necessary.
1194     // - Return a tuple of machine code address to call and the new call frame.
1195     
1196     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1197     
1198     ExecState* execCallee = vm.newCallFrameReturnValue;
1199
1200     loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
1201     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1202     
1203     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1204     execCallee->setCallerFrame(exec);
1205     exec->setCurrentVPC(pc);
1206     
1207     return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1208 }
1209     
1210 LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
1211 {
1212     LLINT_BEGIN_NO_SET_PC();
1213     // This needs to:
1214     // - Figure out what to call and compile it if necessary.
1215     // - Return a tuple of machine code address to call and the new call frame.
1216     
1217     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1218     
1219     ExecState* execCallee = vm.newCallFrameReturnValue;
1220     
1221     loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
1222     LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1223     
1224     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1225     execCallee->setCallerFrame(exec);
1226     exec->setCurrentVPC(pc);
1227     
1228     return setUpCall(execCallee, pc, CodeForConstruct, calleeAsValue);
1229 }
1230     
1231 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1232 {
1233     LLINT_BEGIN_NO_SET_PC();
1234     JSValue calleeAsValue = LLINT_OP(2).jsValue();
1235     
1236     ExecState* execCallee = exec - pc[4].u.operand;
1237     
1238     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1239     execCallee->setCallerFrame(exec);
1240     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1241     execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1242     execCallee->setCodeBlock(0);
1243     exec->setCurrentVPC(pc);
1244     
1245     if (!isHostFunction(calleeAsValue, globalFuncEval))
1246         return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1247     
1248     vm.hostCallReturnValue = eval(execCallee);
1249     LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1250 }
1251
1252 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1253 {
1254     LLINT_BEGIN();
1255     ASSERT(exec->codeBlock()->usesArguments());
1256     Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(VirtualRegister(pc[1].u.operand).offset()).jsValue());
1257     arguments->tearOff(exec);
1258     LLINT_END();
1259 }
1260
1261 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1262 {
1263     LLINT_BEGIN();
1264     LLINT_RETURN(jsStringFromRegisterArray(exec, &LLINT_OP(2), pc[3].u.operand));
1265 }
1266
1267 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1268 {
1269     LLINT_BEGIN();
1270     LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1271 }
1272
1273 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1274 {
1275     LLINT_BEGIN();
1276     JSValue v = LLINT_OP_C(2).jsValue();
1277     JSObject* o = v.toObject(exec);
1278     LLINT_CHECK_EXCEPTION();
1279
1280     int scopeReg = pc[1].u.operand;
1281     JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
1282     exec->uncheckedR(scopeReg) = JSWithScope::create(exec, o, currentScope);
1283     
1284     LLINT_END();
1285 }
1286
1287 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1288 {
1289     LLINT_BEGIN();
1290     int scopeReg = pc[1].u.operand;
1291     JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1292     exec->uncheckedR(scopeReg) = scope->next();
1293     LLINT_END();
1294 }
1295
1296 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1297 {
1298     LLINT_BEGIN();
1299     CodeBlock* codeBlock = exec->codeBlock();
1300     int scopeReg = pc[1].u.operand;
1301     JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
1302     JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[5].u.operand);
1303     JSNameScope* scope = JSNameScope::create(exec, currentScope, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
1304     exec->uncheckedR(scopeReg) = scope;
1305     LLINT_END();
1306 }
1307
1308 LLINT_SLOW_PATH_DECL(slow_path_throw)
1309 {
1310     LLINT_BEGIN();
1311     LLINT_THROW(LLINT_OP_C(1).jsValue());
1312 }
1313
1314 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1315 {
1316     LLINT_BEGIN();
1317     if (pc[2].u.operand)
1318         LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1319     else
1320         LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1321 }
1322
1323 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1324 {
1325     LLINT_BEGIN_NO_SET_PC();
1326     ASSERT(vm.watchdog);
1327     if (UNLIKELY(vm.watchdog->didFire(exec)))
1328         LLINT_THROW(createTerminatedExecutionException(&vm));
1329     LLINT_RETURN_TWO(0, exec);
1330 }
1331
1332 LLINT_SLOW_PATH_DECL(slow_path_debug)
1333 {
1334     LLINT_BEGIN();
1335     int debugHookID = pc[1].u.operand;
1336     vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID));
1337     
1338     LLINT_END();
1339 }
1340
1341 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1342 {
1343     LLINT_BEGIN();
1344     if (LegacyProfiler* profiler = vm.enabledProfiler())
1345         profiler->willExecute(exec, LLINT_OP(1).jsValue());
1346     LLINT_END();
1347 }
1348
1349 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1350 {
1351     LLINT_BEGIN();
1352     if (LegacyProfiler* profiler = vm.enabledProfiler())
1353         profiler->didExecute(exec, LLINT_OP(1).jsValue());
1354     LLINT_END();
1355 }
1356
1357 LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
1358 {
1359     LLINT_BEGIN_NO_SET_PC();
1360     ASSERT(vm.exception());
1361     genericUnwind(&vm, exec, vm.exception());
1362     LLINT_END_IMPL();
1363 }
1364
1365 LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
1366 {
1367     LLINT_BEGIN();
1368     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1369     JSScope* scope = LLINT_OP(2).Register::scope();
1370     LLINT_RETURN(JSScope::resolve(exec, scope, ident));
1371 }
1372
1373 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1374 {
1375     LLINT_BEGIN();
1376
1377     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1378     JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1379     ResolveModeAndType modeAndType(pc[4].u.operand);
1380
1381     PropertySlot slot(scope);
1382     if (!scope->getPropertySlot(exec, ident, slot)) {
1383         if (modeAndType.mode() == ThrowIfNotFound)
1384             LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1385         LLINT_RETURN(jsUndefined());
1386     }
1387
1388     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1389     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1390         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1391             CodeBlock* codeBlock = exec->codeBlock();
1392             Structure* structure = scope->structure(vm);
1393             {
1394                 ConcurrentJITLocker locker(codeBlock->m_lock);
1395                 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
1396                 pc[6].u.operand = slot.cachedOffset();
1397             }
1398             structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
1399         }
1400     }
1401
1402     LLINT_RETURN(slot.getValue(exec, ident));
1403 }
1404
1405 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1406 {
1407     LLINT_BEGIN();
1408
1409     CodeBlock* codeBlock = exec->codeBlock();
1410     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1411     JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1412     JSValue value = LLINT_OP_C(3).jsValue();
1413     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1414     if (modeAndType.type() == LocalClosureVar) {
1415         JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1416         environment->registerAt(pc[6].u.operand).set(vm, environment, value);
1417         if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
1418             set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>");
1419         LLINT_END();
1420     }
1421
1422     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
1423         LLINT_THROW(createUndefinedVariableError(exec, ident));
1424
1425     PutPropertySlot slot(scope, codeBlock->isStrictMode());
1426     scope->methodTable()->put(scope, exec, ident, value, slot);
1427     
1428     CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
1429
1430     LLINT_END();
1431 }
1432
1433 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
1434 {
1435     ExecState* exec = vm->topCallFrame;
1436     if (!exec)
1437         exec = protoFrame->callee()->globalObject()->globalExec();
1438     throwStackOverflowError(exec);
1439     return encodeResult(0, 0);
1440 }
1441
1442 #if !ENABLE(JIT)
1443 extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM* vm, Register* newTopOfStack)
1444 {
1445     bool success = vm->interpreter->stack().ensureCapacityFor(newTopOfStack);
1446     return encodeResult(reinterpret_cast<void*>(success), 0);
1447 }
1448 #endif
1449
1450 extern "C" void llint_write_barrier_slow(ExecState* exec, JSCell* cell)
1451 {
1452     VM& vm = exec->vm();
1453     vm.heap.writeBarrier(cell);
1454 }
1455
1456 extern "C" NO_RETURN_DUE_TO_CRASH void llint_crash()
1457 {
1458     CRASH();
1459 }
1460
1461 } } // namespace JSC::LLInt