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