8561c6760b18efa4a5562d4ed3be4c2d8155a810
[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         vm.throwException(exec, createStackOverflowError(exec));
437         CommonSlowPaths::interpreterThrowInCaller(exec, returnPC);
438         pc = returnToThrowForThrownException(exec);
439     }
440     LLINT_END_IMPL();
441 }
442
443 LLINT_SLOW_PATH_DECL(slow_path_create_activation)
444 {
445     LLINT_BEGIN();
446 #if LLINT_SLOW_PATH_TRACING
447     dataLogF("Creating an activation, exec = %p!\n", exec);
448 #endif
449     JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
450     exec->setScope(activation);
451     LLINT_RETURN(JSValue(activation));
452 }
453
454 LLINT_SLOW_PATH_DECL(slow_path_new_object)
455 {
456     LLINT_BEGIN();
457     LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
458 }
459
460 LLINT_SLOW_PATH_DECL(slow_path_new_array)
461 {
462     LLINT_BEGIN();
463     LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
464 }
465
466 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
467 {
468     LLINT_BEGIN();
469     LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
470 }
471
472 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
473 {
474     LLINT_BEGIN();
475     LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
476 }
477
478 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
479 {
480     LLINT_BEGIN();
481     RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
482     if (!regExp->isValid())
483         LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
484     LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
485 }
486
487 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
488 {
489     LLINT_BEGIN();
490     
491     JSValue value = LLINT_OP_C(2).jsValue();
492     JSValue baseVal = LLINT_OP_C(3).jsValue();
493     if (baseVal.isObject()) {
494         JSObject* baseObject = asObject(baseVal);
495         ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
496         if (baseObject->structure()->typeInfo().implementsHasInstance()) {
497             pc += pc[4].u.operand;
498             LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
499         }
500     }
501     LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
502 }
503
504 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
505 {
506     LLINT_BEGIN();
507     JSValue value = LLINT_OP_C(2).jsValue();
508     JSValue proto = LLINT_OP_C(3).jsValue();
509     ASSERT(!value.isObject() || !proto.isObject());
510     LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
511 }
512
513 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
514 {
515     LLINT_BEGIN();
516     CodeBlock* codeBlock = exec->codeBlock();
517     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
518     JSValue baseValue = LLINT_OP_C(2).jsValue();
519     PropertySlot slot(baseValue);
520
521     JSValue result = baseValue.get(exec, ident, slot);
522     LLINT_CHECK_EXCEPTION();
523     LLINT_OP(1) = result;
524     
525     if (!LLINT_ALWAYS_ACCESS_SLOW
526         && baseValue.isCell()
527         && slot.isCacheable()
528         && slot.slotBase() == baseValue
529         && slot.isCacheableValue()) {
530         
531         JSCell* baseCell = baseValue.asCell();
532         Structure* structure = baseCell->structure();
533         
534         if (!structure->isUncacheableDictionary()
535             && !structure->typeInfo().prohibitsPropertyCaching()) {
536             ConcurrentJITLocker locker(codeBlock->m_lock);
537             
538             pc[4].u.structure.set(
539                 vm, codeBlock->ownerExecutable(), structure);
540             if (isInlineOffset(slot.cachedOffset())) {
541                 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
542                 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
543             } else {
544                 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
545                 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
546             }
547         }
548     }
549
550     if (!LLINT_ALWAYS_ACCESS_SLOW
551         && isJSArray(baseValue)
552         && ident == exec->propertyNames().length) {
553         pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
554 #if ENABLE(VALUE_PROFILER)
555         ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
556         arrayProfile->observeStructure(baseValue.asCell()->structure());
557         pc[4].u.arrayProfile = arrayProfile;
558 #endif
559     }
560
561 #if ENABLE(VALUE_PROFILER)    
562     pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
563 #endif
564     LLINT_END();
565 }
566
567 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
568 {
569     LLINT_BEGIN();
570     CodeBlock* codeBlock = exec->codeBlock();
571     const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
572     JSValue baseValue = LLINT_OP(2).jsValue();
573     PropertySlot slot(baseValue);
574     LLINT_RETURN(baseValue.get(exec, ident, slot));
575 }
576
577 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
578 {
579     LLINT_BEGIN();
580     CodeBlock* codeBlock = exec->codeBlock();
581     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
582     
583     JSValue baseValue = LLINT_OP_C(1).jsValue();
584     PutPropertySlot slot(codeBlock->isStrictMode(), codeBlock->putByIdContext());
585     if (pc[8].u.operand)
586         asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
587     else
588         baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
589     LLINT_CHECK_EXCEPTION();
590     
591     if (!LLINT_ALWAYS_ACCESS_SLOW
592         && baseValue.isCell()
593         && slot.isCacheable()) {
594         
595         JSCell* baseCell = baseValue.asCell();
596         Structure* structure = baseCell->structure();
597         
598         if (!structure->isUncacheableDictionary()
599             && !structure->typeInfo().prohibitsPropertyCaching()
600             && baseCell == slot.base()) {
601             
602             if (slot.type() == PutPropertySlot::NewProperty) {
603                 ConcurrentJITLocker locker(codeBlock->m_lock);
604             
605                 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
606                     ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
607                     
608                     // This is needed because some of the methods we call
609                     // below may GC.
610                     pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
611
612                     if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
613                         ASSERT(structure->previousID()->isObject());
614                         pc[4].u.structure.set(
615                             vm, codeBlock->ownerExecutable(), structure->previousID());
616                         if (isInlineOffset(slot.cachedOffset()))
617                             pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
618                         else
619                             pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
620                         pc[6].u.structure.set(
621                             vm, codeBlock->ownerExecutable(), structure);
622                         StructureChain* chain = structure->prototypeChain(exec);
623                         ASSERT(chain);
624                         pc[7].u.structureChain.set(
625                             vm, codeBlock->ownerExecutable(), chain);
626                     
627                         if (pc[8].u.operand) {
628                             if (isInlineOffset(slot.cachedOffset()))
629                                 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct);
630                             else
631                                 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line);
632                         } else {
633                             if (isInlineOffset(slot.cachedOffset()))
634                                 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal);
635                             else
636                                 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line);
637                         }
638                     }
639                 }
640             } else {
641                 pc[4].u.structure.set(
642                     vm, codeBlock->ownerExecutable(), structure);
643                 if (isInlineOffset(slot.cachedOffset())) {
644                     pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
645                     pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
646                 } else {
647                     pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
648                     pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
649                 }
650             }
651         }
652     }
653     
654     LLINT_END();
655 }
656
657 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
658 {
659     LLINT_BEGIN();
660     CodeBlock* codeBlock = exec->codeBlock();
661     JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
662     bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
663     LLINT_CHECK_EXCEPTION();
664     if (!couldDelete && codeBlock->isStrictMode())
665         LLINT_THROW(createTypeError(exec, "Unable to delete property."));
666     LLINT_RETURN(jsBoolean(couldDelete));
667 }
668
669 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
670 {
671     if (LIKELY(baseValue.isCell() && subscript.isString())) {
672         if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
673             return result;
674     }
675     
676     if (subscript.isUInt32()) {
677         uint32_t i = subscript.asUInt32();
678         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
679             return asString(baseValue)->getIndex(exec, i);
680         
681         return baseValue.get(exec, i);
682     }
683
684     if (isName(subscript))
685         return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
686     
687     Identifier property(exec, subscript.toString(exec)->value(exec));
688     return baseValue.get(exec, property);
689 }
690
691 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
692 {
693     LLINT_BEGIN();
694     LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
695 }
696
697 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
698 {
699     LLINT_BEGIN();
700     JSValue arguments = LLINT_OP(2).jsValue();
701     if (!arguments) {
702         arguments = Arguments::create(vm, exec);
703         LLINT_CHECK_EXCEPTION();
704         LLINT_OP(2) = arguments;
705         exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
706     }
707     
708     LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
709 }
710
711 LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
712 {
713     LLINT_BEGIN();
714     LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
715 }
716
717 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
718 {
719     LLINT_BEGIN();
720     
721     JSValue baseValue = LLINT_OP_C(1).jsValue();
722     JSValue subscript = LLINT_OP_C(2).jsValue();
723     JSValue value = LLINT_OP_C(3).jsValue();
724     
725     if (LIKELY(subscript.isUInt32())) {
726         uint32_t i = subscript.asUInt32();
727         if (baseValue.isObject()) {
728             JSObject* object = asObject(baseValue);
729             if (object->canSetIndexQuickly(i))
730                 object->setIndexQuickly(vm, i, value);
731             else
732                 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
733             LLINT_END();
734         }
735         baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
736         LLINT_END();
737     }
738
739     if (isName(subscript)) {
740         PutPropertySlot slot(exec->codeBlock()->isStrictMode());
741         baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
742         LLINT_END();
743     }
744
745     Identifier property(exec, subscript.toString(exec)->value(exec));
746     LLINT_CHECK_EXCEPTION();
747     PutPropertySlot slot(exec->codeBlock()->isStrictMode());
748     baseValue.put(exec, property, value, slot);
749     LLINT_END();
750 }
751
752 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
753 {
754     LLINT_BEGIN();
755     JSValue baseValue = LLINT_OP_C(2).jsValue();
756     JSObject* baseObject = baseValue.toObject(exec);
757     
758     JSValue subscript = LLINT_OP_C(3).jsValue();
759     
760     bool couldDelete;
761     
762     uint32_t i;
763     if (subscript.getUInt32(i))
764         couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
765     else if (isName(subscript))
766         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
767     else {
768         LLINT_CHECK_EXCEPTION();
769         Identifier property(exec, subscript.toString(exec)->value(exec));
770         LLINT_CHECK_EXCEPTION();
771         couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
772     }
773     
774     if (!couldDelete && exec->codeBlock()->isStrictMode())
775         LLINT_THROW(createTypeError(exec, "Unable to delete property."));
776     
777     LLINT_RETURN(jsBoolean(couldDelete));
778 }
779
780 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
781 {
782     LLINT_BEGIN();
783     JSValue arrayValue = LLINT_OP_C(1).jsValue();
784     ASSERT(isJSArray(arrayValue));
785     asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
786     LLINT_END();
787 }
788
789 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
790 {
791     LLINT_BEGIN();
792     ASSERT(LLINT_OP(1).jsValue().isObject());
793     JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
794     
795     GetterSetter* accessor = GetterSetter::create(exec);
796     LLINT_CHECK_EXCEPTION();
797     
798     JSValue getter = LLINT_OP(3).jsValue();
799     JSValue setter = LLINT_OP(4).jsValue();
800     ASSERT(getter.isObject() || getter.isUndefined());
801     ASSERT(setter.isObject() || setter.isUndefined());
802     ASSERT(getter.isObject() || setter.isObject());
803     
804     if (!getter.isUndefined())
805         accessor->setGetter(vm, asObject(getter));
806     if (!setter.isUndefined())
807         accessor->setSetter(vm, asObject(setter));
808     baseObj->putDirectAccessor(
809         exec,
810         exec->codeBlock()->identifier(pc[2].u.operand),
811         accessor, Accessor);
812     LLINT_END();
813 }
814
815 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
816 {
817     LLINT_BEGIN();
818     LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
819 }
820
821 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
822 {
823     LLINT_BEGIN();
824     LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
825 }
826
827 LLINT_SLOW_PATH_DECL(slow_path_jless)
828 {
829     LLINT_BEGIN();
830     LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
831 }
832
833 LLINT_SLOW_PATH_DECL(slow_path_jnless)
834 {
835     LLINT_BEGIN();
836     LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
837 }
838
839 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
840 {
841     LLINT_BEGIN();
842     LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
843 }
844
845 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
846 {
847     LLINT_BEGIN();
848     LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
849 }
850
851 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
852 {
853     LLINT_BEGIN();
854     LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
855 }
856
857 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
858 {
859     LLINT_BEGIN();
860     LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
861 }
862
863 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
864 {
865     LLINT_BEGIN();
866     LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
867 }
868
869 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
870 {
871     LLINT_BEGIN();
872     LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
873 }
874
875 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
876 {
877     LLINT_BEGIN();
878     JSValue scrutinee = LLINT_OP_C(3).jsValue();
879     ASSERT(scrutinee.isDouble());
880     double value = scrutinee.asDouble();
881     int32_t intValue = static_cast<int32_t>(value);
882     int defaultOffset = pc[2].u.operand;
883     if (value == intValue) {
884         CodeBlock* codeBlock = exec->codeBlock();
885         pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
886     } else
887         pc += defaultOffset;
888     LLINT_END();
889 }
890
891 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
892 {
893     LLINT_BEGIN();
894     JSValue scrutinee = LLINT_OP_C(3).jsValue();
895     ASSERT(scrutinee.isString());
896     JSString* string = asString(scrutinee);
897     ASSERT(string->length() == 1);
898     int defaultOffset = pc[2].u.operand;
899     StringImpl* impl = string->value(exec).impl();
900     CodeBlock* codeBlock = exec->codeBlock();
901     pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
902     LLINT_END();
903 }
904
905 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
906 {
907     LLINT_BEGIN();
908     JSValue scrutinee = LLINT_OP_C(3).jsValue();
909     int defaultOffset = pc[2].u.operand;
910     if (!scrutinee.isString())
911         pc += defaultOffset;
912     else {
913         CodeBlock* codeBlock = exec->codeBlock();
914         pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
915     }
916     LLINT_END();
917 }
918
919 LLINT_SLOW_PATH_DECL(slow_path_new_func)
920 {
921     LLINT_BEGIN();
922     CodeBlock* codeBlock = exec->codeBlock();
923     ASSERT(codeBlock->codeType() != FunctionCode
924            || !codeBlock->needsFullScopeChain()
925            || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
926 #if LLINT_SLOW_PATH_TRACING
927     dataLogF("Creating function!\n");
928 #endif
929     LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
930 }
931
932 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
933 {
934     LLINT_BEGIN();
935     CodeBlock* codeBlock = exec->codeBlock();
936     FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
937     JSFunction* func = JSFunction::create(exec, function, exec->scope());
938     
939     LLINT_RETURN(func);
940 }
941
942 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
943 {
944     ExecState* exec = execCallee->callerFrame();
945     VM& vm = exec->vm();
946
947     execCallee->setScope(exec->scope());
948     execCallee->setCodeBlock(0);
949     execCallee->clearReturnPC();
950
951     if (kind == CodeForCall) {
952         CallData callData;
953         CallType callType = getCallData(callee, callData);
954     
955         ASSERT(callType != CallTypeJS);
956     
957         if (callType == CallTypeHost) {
958             NativeCallFrameTracer tracer(&vm, execCallee);
959             execCallee->setCallee(asObject(callee));
960             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
961             
962             LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
963         }
964         
965 #if LLINT_SLOW_PATH_TRACING
966         dataLog("Call callee is not a function: ", callee, "\n");
967 #endif
968
969         ASSERT(callType == CallTypeNone);
970         LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
971     }
972
973     ASSERT(kind == CodeForConstruct);
974     
975     ConstructData constructData;
976     ConstructType constructType = getConstructData(callee, constructData);
977     
978     ASSERT(constructType != ConstructTypeJS);
979     
980     if (constructType == ConstructTypeHost) {
981         NativeCallFrameTracer tracer(&vm, execCallee);
982         execCallee->setCallee(asObject(callee));
983         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
984
985         LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
986     }
987     
988 #if LLINT_SLOW_PATH_TRACING
989     dataLog("Constructor callee is not a function: ", callee, "\n");
990 #endif
991
992     ASSERT(constructType == ConstructTypeNone);
993     LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
994 }
995
996 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
997 {
998 #if LLINT_SLOW_PATH_TRACING
999     dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
1000 #endif
1001
1002     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1003     if (!calleeAsFunctionCell)
1004         return handleHostCall(execCallee, pc, calleeAsValue, kind);
1005     
1006     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1007     JSScope* scope = callee->scopeUnchecked();
1008     VM& vm = *scope->vm();
1009     execCallee->setScope(scope);
1010     ExecutableBase* executable = callee->executable();
1011     
1012     MacroAssemblerCodePtr codePtr;
1013     CodeBlock* codeBlock = 0;
1014     if (executable->isHostFunction())
1015         codePtr = executable->hostCodeEntryFor(kind);
1016     else {
1017         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1018         JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
1019         if (error)
1020             LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1021         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1022         ASSERT(codeBlock);
1023         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1024             codePtr = functionExecutable->jsCodeWithArityCheckEntryFor(kind);
1025         else
1026             codePtr = functionExecutable->jsCodeEntryFor(kind);
1027     }
1028     
1029     if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1030         ExecState* execCaller = execCallee->callerFrame();
1031         
1032         CodeBlock* callerCodeBlock = execCaller->codeBlock();
1033
1034         ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1035         
1036         if (callLinkInfo->isOnList())
1037             callLinkInfo->remove();
1038         callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1039         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1040         callLinkInfo->machineCodeTarget = codePtr;
1041         if (codeBlock)
1042             codeBlock->linkIncomingCall(execCaller, callLinkInfo);
1043     }
1044
1045     LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1046 }
1047
1048 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1049 {
1050     // This needs to:
1051     // - Set up a call frame.
1052     // - Figure out what to call and compile it if necessary.
1053     // - If possible, link the call's inline cache.
1054     // - Return a tuple of machine code address to call and the new call frame.
1055     
1056     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1057     
1058     ExecState* execCallee = exec + pc[4].u.operand;
1059     
1060     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1061     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1062     execCallee->setCallerFrame(exec);
1063     
1064     ASSERT(pc[5].u.callLinkInfo);
1065     return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1066 }
1067
1068 LLINT_SLOW_PATH_DECL(slow_path_call)
1069 {
1070     LLINT_BEGIN_NO_SET_PC();
1071     return genericCall(exec, pc, CodeForCall);
1072 }
1073
1074 LLINT_SLOW_PATH_DECL(slow_path_construct)
1075 {
1076     LLINT_BEGIN_NO_SET_PC();
1077     return genericCall(exec, pc, CodeForConstruct);
1078 }
1079
1080 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1081 {
1082     LLINT_BEGIN();
1083     // This needs to:
1084     // - Set up a call frame while respecting the variable arguments.
1085     // - Figure out what to call and compile it if necessary.
1086     // - Return a tuple of machine code address to call and the new call frame.
1087     
1088     JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1089     
1090     ExecState* execCallee = loadVarargs(
1091         exec, &vm.interpreter->stack(),
1092         LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[5].u.operand);
1093     LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1094     
1095     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1096     execCallee->setCallerFrame(exec);
1097     exec->setCurrentVPC(pc);
1098     
1099     return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1100 }
1101
1102 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1103 {
1104     LLINT_BEGIN_NO_SET_PC();
1105     JSValue calleeAsValue = LLINT_OP(2).jsValue();
1106     
1107     ExecState* execCallee = exec + pc[4].u.operand;
1108     
1109     execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1110     execCallee->setCallerFrame(exec);
1111     execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1112     execCallee->setScope(exec->scope());
1113     execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1114     execCallee->setCodeBlock(0);
1115     exec->setCurrentVPC(pc);
1116     
1117     if (!isHostFunction(calleeAsValue, globalFuncEval))
1118         return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1119     
1120     vm.hostCallReturnValue = eval(execCallee);
1121     LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1122 }
1123
1124 LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1125 {
1126     LLINT_BEGIN();
1127     ASSERT(exec->codeBlock()->needsFullScopeChain());
1128     jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
1129     LLINT_END();
1130 }
1131
1132 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1133 {
1134     LLINT_BEGIN();
1135     ASSERT(exec->codeBlock()->usesArguments());
1136     Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
1137     if (JSValue activationValue = LLINT_OP_C(2).jsValue())
1138         arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
1139     else
1140         arguments->tearOff(exec);
1141     LLINT_END();
1142 }
1143
1144 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1145 {
1146     LLINT_BEGIN();
1147     LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1148 }
1149
1150 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1151 {
1152     LLINT_BEGIN();
1153     LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1154 }
1155
1156 LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1157 {
1158     LLINT_BEGIN();
1159     JSValue v = LLINT_OP(2).jsValue();
1160     if (v.isUndefinedOrNull()) {
1161         pc += pc[5].u.operand;
1162         LLINT_END();
1163     }
1164     
1165     JSObject* o = v.toObject(exec);
1166     Structure* structure = o->structure();
1167     JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1168     if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1169         jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1170     
1171     LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1172     LLINT_OP(2) = JSValue(o);
1173     LLINT_OP(3) = Register::withInt(0);
1174     LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1175     
1176     pc += OPCODE_LENGTH(op_get_pnames);
1177     LLINT_END();
1178 }
1179
1180 LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1181 {
1182     LLINT_BEGIN();
1183     JSObject* base = asObject(LLINT_OP(2).jsValue());
1184     JSString* property = asString(LLINT_OP(1).jsValue());
1185     if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1186         // Go to target.
1187         pc += pc[6].u.operand;
1188     } // Else, don't change the PC, so the interpreter will reloop.
1189     LLINT_END();
1190 }
1191
1192 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1193 {
1194     LLINT_BEGIN();
1195     JSValue v = LLINT_OP_C(1).jsValue();
1196     JSObject* o = v.toObject(exec);
1197     LLINT_CHECK_EXCEPTION();
1198     
1199     exec->setScope(JSWithScope::create(exec, o));
1200     
1201     LLINT_END();
1202 }
1203
1204 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1205 {
1206     LLINT_BEGIN();
1207     exec->setScope(exec->scope()->next());
1208     LLINT_END();
1209 }
1210
1211 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1212 {
1213     LLINT_BEGIN();
1214     CodeBlock* codeBlock = exec->codeBlock();
1215     JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
1216     exec->setScope(scope);
1217     LLINT_END();
1218 }
1219
1220 LLINT_SLOW_PATH_DECL(slow_path_throw)
1221 {
1222     LLINT_BEGIN();
1223     LLINT_THROW(LLINT_OP_C(1).jsValue());
1224 }
1225
1226 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1227 {
1228     LLINT_BEGIN();
1229     if (pc[2].u.operand)
1230         LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1231     else
1232         LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1233 }
1234
1235 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1236 {
1237     LLINT_BEGIN_NO_SET_PC();
1238     if (UNLIKELY(vm.watchdog.didFire(exec)))
1239         LLINT_THROW(createTerminatedExecutionException(&vm));
1240     LLINT_RETURN_TWO(0, exec);
1241 }
1242
1243 LLINT_SLOW_PATH_DECL(slow_path_debug)
1244 {
1245     LLINT_BEGIN();
1246     int debugHookID = pc[1].u.operand;
1247     int firstLine = pc[2].u.operand;
1248     int lastLine = pc[3].u.operand;
1249     int column = pc[4].u.operand;
1250
1251     vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
1252     
1253     LLINT_END();
1254 }
1255
1256 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1257 {
1258     LLINT_BEGIN();
1259     if (LegacyProfiler* profiler = vm.enabledProfiler())
1260         profiler->willExecute(exec, LLINT_OP(1).jsValue());
1261     LLINT_END();
1262 }
1263
1264 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1265 {
1266     LLINT_BEGIN();
1267     if (LegacyProfiler* profiler = vm.enabledProfiler())
1268         profiler->didExecute(exec, LLINT_OP(1).jsValue());
1269     LLINT_END();
1270 }
1271
1272 LLINT_SLOW_PATH_DECL(throw_from_native_call)
1273 {
1274     LLINT_BEGIN();
1275     ASSERT(vm.exception());
1276     LLINT_END();
1277 }
1278
1279 LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
1280 {
1281     LLINT_BEGIN();
1282     const Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
1283     LLINT_RETURN(JSScope::resolve(exec, exec->scope(), ident));
1284 }
1285
1286 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1287 {
1288     LLINT_BEGIN();
1289     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1290     JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1291     ResolveModeAndType modeAndType(pc[4].u.operand);
1292
1293     PropertySlot slot(scope);
1294     if (!scope->getPropertySlot(exec, ident, slot)) {
1295         if (modeAndType.mode() == ThrowIfNotFound)
1296             LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1297         LLINT_RETURN(jsUndefined());
1298     }
1299
1300     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1301     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1302         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1303             CodeBlock* codeBlock = exec->codeBlock();
1304             ConcurrentJITLocker locker(codeBlock->m_lock);
1305             pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
1306             pc[6].u.operand = slot.cachedOffset();
1307         }
1308     }
1309
1310     LLINT_RETURN(slot.getValue(exec, ident));
1311 }
1312
1313 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1314 {
1315     LLINT_BEGIN();
1316     CodeBlock* codeBlock = exec->codeBlock();
1317     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1318     JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1319     JSValue value = LLINT_OP_C(3).jsValue();
1320     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1321
1322     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
1323         LLINT_THROW(createUndefinedVariableError(exec, ident));
1324
1325     PutPropertySlot slot(codeBlock->isStrictMode());
1326     scope->methodTable()->put(scope, exec, ident, value, slot);
1327
1328     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1329     if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1330         if (slot.isCacheable() && slot.base() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1331             ConcurrentJITLocker locker(codeBlock->m_lock);
1332             pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
1333             pc[6].u.operand = slot.cachedOffset();
1334         }
1335     }
1336
1337     LLINT_END();
1338 }
1339
1340 } } // namespace JSC::LLInt
1341
1342 #endif // ENABLE(LLINT)