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