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