]> git.saurik.com Git - apple/javascriptcore.git/blame - llint/LLIntSlowPaths.cpp
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / llint / LLIntSlowPaths.cpp
CommitLineData
6fe7ccc8 1/*
93a37866 2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
6fe7ccc8
A
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"
93a37866 32#include "ArrayConstructor.h"
6fe7ccc8
A
33#include "CallFrame.h"
34#include "CommonSlowPaths.h"
35#include "GetterSetter.h"
36#include "HostCallReturnValue.h"
37#include "Interpreter.h"
38#include "JIT.h"
39#include "JITDriver.h"
40#include "JSActivation.h"
93a37866 41#include "JSCJSValue.h"
6fe7ccc8 42#include "JSGlobalObjectFunctions.h"
93a37866 43#include "JSNameScope.h"
6fe7ccc8 44#include "JSPropertyNameIterator.h"
6fe7ccc8 45#include "JSString.h"
93a37866 46#include "JSWithScope.h"
6fe7ccc8
A
47#include "LLIntCommon.h"
48#include "LLIntExceptions.h"
49#include "LowLevelInterpreter.h"
93a37866 50#include "ObjectConstructor.h"
6fe7ccc8 51#include "Operations.h"
93a37866
A
52#include "StructureRareDataInlines.h"
53#include <wtf/StringPrintStream.h>
6fe7ccc8
A
54
55namespace JSC { namespace LLInt {
56
57#define LLINT_BEGIN_NO_SET_PC() \
93a37866
A
58 VM& vm = exec->vm(); \
59 NativeCallFrameTracer tracer(&vm, exec)
6fe7ccc8
A
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 { \
93a37866 86 vm.exception = (exceptionToThrow); \
6fe7ccc8
A
87 pc = returnToThrow(exec, pc); \
88 LLINT_END_IMPL(); \
89 } while (false)
90
91#define LLINT_CHECK_EXCEPTION() do { \
93a37866 92 if (UNLIKELY(vm.exception)) { \
6fe7ccc8
A
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; \
93a37866 125 LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \
6fe7ccc8
A
126 LLINT_END_IMPL(); \
127 } while (false)
93a37866
A
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
6fe7ccc8
A
134#else // ENABLE(VALUE_PROFILER)
135#define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
93a37866
A
136
137#define LLINT_PROFILE_VALUE(opcode, value) do { } while (false)
138
6fe7ccc8
A
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); \
93a37866 146 vm.exception = (exceptionToThrow); \
6fe7ccc8
A
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); \
93a37866 153 if (UNLIKELY(vm.exception)) \
6fe7ccc8
A
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
165extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
166{
167 LLINT_BEGIN();
93a37866 168 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
6fe7ccc8
A
169 exec->codeBlock(),
170 exec,
171 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
93a37866 172 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
6fe7ccc8
A
173 fromWhere,
174 operand,
175 pc[operand].u.operand);
176 LLINT_END();
177}
178
179extern "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);
93a37866
A
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());
6fe7ccc8
A
202 LLINT_END_IMPL();
203}
204
205LLINT_SLOW_PATH_DECL(trace_prologue)
206{
93a37866 207 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
6fe7ccc8
A
208 LLINT_END_IMPL();
209}
210
211static 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);
93a37866 216 dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
6fe7ccc8
A
217 codeBlock, exec, comment, callee, executable,
218 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
219 exec->callerFrame());
220}
221
222LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
223{
224 traceFunctionPrologue(exec, "call prologue", CodeForCall);
225 LLINT_END_IMPL();
226}
227
228LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
229{
230 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
231 LLINT_END_IMPL();
232}
233
234LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
235{
236 traceFunctionPrologue(exec, "call arity check", CodeForCall);
237 LLINT_END_IMPL();
238}
239
240LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
241{
242 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
243 LLINT_END_IMPL();
244}
245
246LLINT_SLOW_PATH_DECL(trace)
247{
93a37866 248 dataLogF("%p / %p: executing bc#%zu, %s, scope %p\n",
6fe7ccc8
A
249 exec->codeBlock(),
250 exec,
251 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
93a37866
A
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());
6fe7ccc8
A
257 }
258 LLINT_END_IMPL();
259}
260
261LLINT_SLOW_PATH_DECL(special_trace)
262{
93a37866 263 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
6fe7ccc8
A
264 exec->codeBlock(),
265 exec,
266 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
93a37866 267 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
6fe7ccc8
A
268 exec->returnPC().value());
269 LLINT_END_IMPL();
270}
271
93a37866 272#if ENABLE(JIT)
6fe7ccc8
A
273inline bool shouldJIT(ExecState* exec)
274{
275 // You can modify this to turn off JITting without rebuilding the world.
93a37866 276 return exec->vm().canUseJIT();
6fe7ccc8
A
277}
278
279// Returns true if we should try to OSR.
280inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
281{
93a37866
A
282 codeBlock->updateAllValueProfilePredictions();
283
6fe7ccc8
A
284 if (!codeBlock->checkIfJITThresholdReached()) {
285#if ENABLE(JIT_VERBOSE_OSR)
93a37866 286 dataLogF(" JIT threshold should be lifted.\n");
6fe7ccc8
A
287#endif
288 return false;
289 }
290
93a37866 291 CodeBlock::JITCompilationResult result = codeBlock->jitCompile(exec);
6fe7ccc8
A
292 switch (result) {
293 case CodeBlock::AlreadyCompiled:
294#if ENABLE(JIT_VERBOSE_OSR)
93a37866 295 dataLogF(" Code was already compiled.\n");
6fe7ccc8
A
296#endif
297 codeBlock->jitSoon();
298 return true;
299 case CodeBlock::CouldNotCompile:
300#if ENABLE(JIT_VERBOSE_OSR)
93a37866 301 dataLogF(" JIT compilation failed.\n");
6fe7ccc8
A
302#endif
303 codeBlock->dontJITAnytimeSoon();
304 return false;
305 case CodeBlock::CompiledSuccessfully:
306#if ENABLE(JIT_VERBOSE_OSR)
93a37866 307 dataLogF(" JIT compilation successful.\n");
6fe7ccc8
A
308#endif
309 codeBlock->jitSoon();
310 return true;
311 }
93a37866 312 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
313 return false;
314}
315
316enum EntryKind { Prologue, ArityCheck };
93a37866 317static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
6fe7ccc8
A
318{
319#if ENABLE(JIT_VERBOSE_OSR)
93a37866
A
320 dataLog(*codeBlock, ": Entered ", name, " with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
321#else
322 UNUSED_PARAM(name);
6fe7ccc8
A
323#endif
324
325 if (!shouldJIT(exec)) {
326 codeBlock->dontJITAnytimeSoon();
327 LLINT_RETURN_TWO(0, exec);
328 }
329 if (!jitCompileAndSetHeuristics(codeBlock, exec))
330 LLINT_RETURN_TWO(0, exec);
331
332 if (kind == Prologue)
333 LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
334 ASSERT(kind == ArityCheck);
335 LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
336}
337
338LLINT_SLOW_PATH_DECL(entry_osr)
339{
340 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
341}
342
343LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
344{
345 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
346}
347
348LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
349{
350 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
351}
352
353LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
354{
355 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
356}
357
358LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
359{
360 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
361}
362
363LLINT_SLOW_PATH_DECL(loop_osr)
364{
365 CodeBlock* codeBlock = exec->codeBlock();
366
367#if ENABLE(JIT_VERBOSE_OSR)
93a37866 368 dataLog(*codeBlock, ": Entered loop_osr with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
6fe7ccc8
A
369#endif
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->getJITType() == JITCode::BaselineJIT);
380
381 Vector<BytecodeAndMachineOffset> map;
382 codeBlock->jitCodeMap()->decode(map);
93a37866 383 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
6fe7ccc8
A
384 ASSERT(mapping);
385 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
386
387 void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
388 ASSERT(jumpTarget);
389
390 LLINT_RETURN_TWO(jumpTarget, exec);
391}
392
393LLINT_SLOW_PATH_DECL(replace)
394{
395 CodeBlock* codeBlock = exec->codeBlock();
396
397#if ENABLE(JIT_VERBOSE_OSR)
93a37866 398 dataLog(*codeBlock, ": Entered replace with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
6fe7ccc8
A
399#endif
400
401 if (shouldJIT(exec))
402 jitCompileAndSetHeuristics(codeBlock, exec);
403 else
404 codeBlock->dontJITAnytimeSoon();
405 LLINT_END_IMPL();
406}
93a37866 407#endif // ENABLE(JIT)
6fe7ccc8 408
93a37866 409LLINT_SLOW_PATH_DECL(stack_check)
6fe7ccc8
A
410{
411 LLINT_BEGIN();
412#if LLINT_SLOW_PATH_TRACING
93a37866
A
413 dataLogF("Checking stack height with exec = %p.\n", exec);
414 dataLogF("CodeBlock = %p.\n", exec->codeBlock());
415 dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
416 dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
417 dataLogF("Current end is at %p.\n", exec->vm().interpreter->stack().end());
6fe7ccc8 418#endif
93a37866
A
419 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->vm().interpreter->stack().end());
420 if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
6fe7ccc8
A
421 ReturnAddressPtr returnPC = exec->returnPC();
422 exec = exec->callerFrame();
93a37866 423 vm.exception = createStackOverflowError(exec);
6fe7ccc8
A
424 interpreterThrowInCaller(exec, returnPC);
425 pc = returnToThrowForThrownException(exec);
426 }
427 LLINT_END_IMPL();
428}
429
430LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
431{
432 LLINT_BEGIN();
93a37866 433 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall);
6fe7ccc8
A
434 if (!newExec) {
435 ReturnAddressPtr returnPC = exec->returnPC();
436 exec = exec->callerFrame();
93a37866 437 vm.exception = createStackOverflowError(exec);
6fe7ccc8
A
438 interpreterThrowInCaller(exec, returnPC);
439 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
440 }
441 LLINT_RETURN_TWO(0, newExec);
442}
443
444LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck)
445{
446 LLINT_BEGIN();
93a37866 447 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct);
6fe7ccc8
A
448 if (!newExec) {
449 ReturnAddressPtr returnPC = exec->returnPC();
450 exec = exec->callerFrame();
93a37866 451 vm.exception = createStackOverflowError(exec);
6fe7ccc8
A
452 interpreterThrowInCaller(exec, returnPC);
453 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
454 }
455 LLINT_RETURN_TWO(0, newExec);
456}
457
458LLINT_SLOW_PATH_DECL(slow_path_create_activation)
459{
460 LLINT_BEGIN();
461#if LLINT_SLOW_PATH_TRACING
93a37866 462 dataLogF("Creating an activation, exec = %p!\n", exec);
6fe7ccc8 463#endif
93a37866
A
464 JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
465 exec->setScope(activation);
6fe7ccc8
A
466 LLINT_RETURN(JSValue(activation));
467}
468
469LLINT_SLOW_PATH_DECL(slow_path_create_arguments)
470{
471 LLINT_BEGIN();
93a37866 472 JSValue arguments = JSValue(Arguments::create(vm, exec));
6fe7ccc8
A
473 LLINT_CHECK_EXCEPTION();
474 exec->uncheckedR(pc[1].u.operand) = arguments;
475 exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
476 LLINT_END();
477}
478
479LLINT_SLOW_PATH_DECL(slow_path_create_this)
480{
481 LLINT_BEGIN();
93a37866 482 JSFunction* constructor = jsCast<JSFunction*>(LLINT_OP(2).jsValue().asCell());
6fe7ccc8
A
483
484#if !ASSERT_DISABLED
485 ConstructData constructData;
486 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
487#endif
93a37866
A
488
489 size_t inlineCapacity = pc[3].u.operand;
490 Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure();
6fe7ccc8
A
491 LLINT_RETURN(constructEmptyObject(exec, structure));
492}
493
494LLINT_SLOW_PATH_DECL(slow_path_convert_this)
495{
496 LLINT_BEGIN();
497 JSValue v1 = LLINT_OP(1).jsValue();
498 ASSERT(v1.isPrimitive());
93a37866
A
499#if ENABLE(VALUE_PROFILER)
500 pc[OPCODE_LENGTH(op_convert_this) - 1].u.profile->m_buckets[0] =
501 JSValue::encode(v1.structureOrUndefined());
502#endif
6fe7ccc8
A
503 LLINT_RETURN(v1.toThisObject(exec));
504}
505
506LLINT_SLOW_PATH_DECL(slow_path_new_object)
507{
508 LLINT_BEGIN();
93a37866 509 LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
6fe7ccc8
A
510}
511
512LLINT_SLOW_PATH_DECL(slow_path_new_array)
513{
514 LLINT_BEGIN();
93a37866
A
515 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
516}
517
518LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
519{
520 LLINT_BEGIN();
521 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
6fe7ccc8
A
522}
523
524LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
525{
526 LLINT_BEGIN();
93a37866 527 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
6fe7ccc8
A
528}
529
530LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
531{
532 LLINT_BEGIN();
533 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
534 if (!regExp->isValid())
535 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
93a37866 536 LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
6fe7ccc8
A
537}
538
539LLINT_SLOW_PATH_DECL(slow_path_not)
540{
541 LLINT_BEGIN();
542 LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
543}
544
545LLINT_SLOW_PATH_DECL(slow_path_eq)
546{
547 LLINT_BEGIN();
548 LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
549}
550
551LLINT_SLOW_PATH_DECL(slow_path_neq)
552{
553 LLINT_BEGIN();
554 LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
555}
556
557LLINT_SLOW_PATH_DECL(slow_path_stricteq)
558{
559 LLINT_BEGIN();
560 LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
561}
562
563LLINT_SLOW_PATH_DECL(slow_path_nstricteq)
564{
565 LLINT_BEGIN();
566 LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
567}
568
569LLINT_SLOW_PATH_DECL(slow_path_less)
570{
571 LLINT_BEGIN();
572 LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
573}
574
575LLINT_SLOW_PATH_DECL(slow_path_lesseq)
576{
577 LLINT_BEGIN();
578 LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
579}
580
581LLINT_SLOW_PATH_DECL(slow_path_greater)
582{
583 LLINT_BEGIN();
584 LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
585}
586
587LLINT_SLOW_PATH_DECL(slow_path_greatereq)
588{
589 LLINT_BEGIN();
590 LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
591}
592
593LLINT_SLOW_PATH_DECL(slow_path_pre_inc)
594{
595 LLINT_BEGIN();
596 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
597}
598
599LLINT_SLOW_PATH_DECL(slow_path_pre_dec)
600{
601 LLINT_BEGIN();
602 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
603}
604
93a37866 605LLINT_SLOW_PATH_DECL(slow_path_to_number)
6fe7ccc8
A
606{
607 LLINT_BEGIN();
608 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
609}
610
611LLINT_SLOW_PATH_DECL(slow_path_negate)
612{
613 LLINT_BEGIN();
614 LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
615}
616
617LLINT_SLOW_PATH_DECL(slow_path_add)
618{
619 LLINT_BEGIN();
620 JSValue v1 = LLINT_OP_C(2).jsValue();
621 JSValue v2 = LLINT_OP_C(3).jsValue();
622
623#if LLINT_SLOW_PATH_TRACING
93a37866 624 dataLog("Trying to add ", v1, " to ", v2, ".\n");
6fe7ccc8
A
625#endif
626
627 if (v1.isString() && !v2.isObject())
628 LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
629
630 if (v1.isNumber() && v2.isNumber())
631 LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
632
633 LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
634}
635
93a37866
A
636// The following arithmetic and bitwise operations need to be sure to run
637// toNumber() on their operands in order. (A call to toNumber() is idempotent
638// if an exception is already set on the ExecState.)
639
6fe7ccc8
A
640LLINT_SLOW_PATH_DECL(slow_path_mul)
641{
642 LLINT_BEGIN();
93a37866
A
643 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
644 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
645 LLINT_RETURN(jsNumber(a * b));
6fe7ccc8
A
646}
647
648LLINT_SLOW_PATH_DECL(slow_path_sub)
649{
650 LLINT_BEGIN();
93a37866
A
651 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
652 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
653 LLINT_RETURN(jsNumber(a - b));
6fe7ccc8
A
654}
655
656LLINT_SLOW_PATH_DECL(slow_path_div)
657{
658 LLINT_BEGIN();
93a37866
A
659 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
660 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
661 LLINT_RETURN(jsNumber(a / b));
6fe7ccc8
A
662}
663
664LLINT_SLOW_PATH_DECL(slow_path_mod)
665{
666 LLINT_BEGIN();
93a37866
A
667 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
668 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
669 LLINT_RETURN(jsNumber(fmod(a, b)));
6fe7ccc8
A
670}
671
672LLINT_SLOW_PATH_DECL(slow_path_lshift)
673{
674 LLINT_BEGIN();
93a37866
A
675 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
676 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
677 LLINT_RETURN(jsNumber(a << (b & 31)));
6fe7ccc8
A
678}
679
680LLINT_SLOW_PATH_DECL(slow_path_rshift)
681{
682 LLINT_BEGIN();
93a37866
A
683 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
684 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
685 LLINT_RETURN(jsNumber(a >> (b & 31)));
6fe7ccc8
A
686}
687
688LLINT_SLOW_PATH_DECL(slow_path_urshift)
689{
690 LLINT_BEGIN();
93a37866
A
691 uint32_t a = LLINT_OP_C(2).jsValue().toUInt32(exec);
692 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
693 LLINT_RETURN(jsNumber(a >> (b & 31)));
6fe7ccc8
A
694}
695
696LLINT_SLOW_PATH_DECL(slow_path_bitand)
697{
698 LLINT_BEGIN();
93a37866
A
699 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
700 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
701 LLINT_RETURN(jsNumber(a & b));
6fe7ccc8
A
702}
703
704LLINT_SLOW_PATH_DECL(slow_path_bitor)
705{
706 LLINT_BEGIN();
93a37866
A
707 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
708 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
709 LLINT_RETURN(jsNumber(a | b));
6fe7ccc8
A
710}
711
712LLINT_SLOW_PATH_DECL(slow_path_bitxor)
713{
714 LLINT_BEGIN();
93a37866
A
715 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
716 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
717 LLINT_RETURN(jsNumber(a ^ b));
6fe7ccc8
A
718}
719
720LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
721{
722 LLINT_BEGIN();
93a37866
A
723
724 JSValue value = LLINT_OP_C(2).jsValue();
725 JSValue baseVal = LLINT_OP_C(3).jsValue();
726 if (baseVal.isObject()) {
727 JSObject* baseObject = asObject(baseVal);
728 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
729 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
730 pc += pc[4].u.operand;
731 LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
732 }
733 }
6fe7ccc8
A
734 LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
735}
736
737LLINT_SLOW_PATH_DECL(slow_path_instanceof)
738{
739 LLINT_BEGIN();
93a37866
A
740 JSValue value = LLINT_OP_C(2).jsValue();
741 JSValue proto = LLINT_OP_C(3).jsValue();
742 ASSERT(!value.isObject() || !proto.isObject());
743 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
6fe7ccc8
A
744}
745
746LLINT_SLOW_PATH_DECL(slow_path_typeof)
747{
748 LLINT_BEGIN();
749 LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
750}
751
752LLINT_SLOW_PATH_DECL(slow_path_is_object)
753{
754 LLINT_BEGIN();
93a37866 755 LLINT_RETURN(jsBoolean(jsIsObjectType(exec, LLINT_OP_C(2).jsValue())));
6fe7ccc8
A
756}
757
758LLINT_SLOW_PATH_DECL(slow_path_is_function)
759{
760 LLINT_BEGIN();
761 LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
762}
763
764LLINT_SLOW_PATH_DECL(slow_path_in)
765{
766 LLINT_BEGIN();
767 LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
768}
769
770LLINT_SLOW_PATH_DECL(slow_path_resolve)
771{
772 LLINT_BEGIN();
93a37866
A
773 Identifier ident = exec->codeBlock()->identifier(pc[2].u.operand);
774 ResolveOperations* operations = pc[3].u.resolveOperations;
775 JSValue result = JSScope::resolve(exec, ident, operations);
776 ASSERT(operations->size());
777 if (operations->isEmpty())
778 LLINT_RETURN_PROFILED(op_resolve, result);
6fe7ccc8 779
93a37866
A
780 switch (operations->data()[0].m_operation) {
781 case ResolveOperation::GetAndReturnGlobalProperty:
782 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_property);
783 break;
6fe7ccc8 784
93a37866
A
785 case ResolveOperation::GetAndReturnGlobalVar:
786 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_var);
787 break;
6fe7ccc8 788
93a37866
A
789 case ResolveOperation::SkipTopScopeNode:
790 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_with_top_scope_check);
791 break;
6fe7ccc8 792
93a37866
A
793 case ResolveOperation::SkipScopes:
794 if (operations->data()[0].m_scopesToSkip)
795 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var);
796 else
797 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_on_top_scope);
798 break;
799
800 default:
801 break;
802 }
803 LLINT_RETURN_PROFILED(op_resolve, result);
6fe7ccc8
A
804}
805
93a37866 806LLINT_SLOW_PATH_DECL(slow_path_put_to_base)
6fe7ccc8
A
807{
808 LLINT_BEGIN();
93a37866
A
809 PutToBaseOperation* operation = pc[4].u.putToBaseOperation;
810 JSScope::resolvePut(exec, LLINT_OP_C(1).jsValue(), exec->codeBlock()->identifier(pc[2].u.operand), LLINT_OP_C(3).jsValue(), operation);
811 switch (operation->m_kind) {
812 case PutToBaseOperation::VariablePut:
813 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_to_base_variable);
814 break;
815
816 default:
817 break;
818 }
819 LLINT_END();
6fe7ccc8
A
820}
821
822LLINT_SLOW_PATH_DECL(slow_path_resolve_base)
823{
824 LLINT_BEGIN();
825 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
93a37866
A
826 ResolveOperations* operations = pc[4].u.resolveOperations;
827 JSValue result;
6fe7ccc8 828 if (pc[3].u.operand) {
93a37866
A
829 result = JSScope::resolveBase(exec, ident, true, operations, pc[5].u.putToBaseOperation);
830 if (!result)
831 LLINT_THROW(vm.exception);
832 } else
833 result = JSScope::resolveBase(exec, ident, false, operations, pc[5].u.putToBaseOperation);
834
835 ASSERT(operations->size());
836 if (operations->isEmpty()) {
837 LLINT_PROFILE_VALUE(op_resolve_base, result);
838 LLINT_RETURN(result);
6fe7ccc8 839 }
6fe7ccc8 840
93a37866
A
841 switch (operations->data()[0].m_operation) {
842 case ResolveOperation::ReturnGlobalObjectAsBase:
843 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_global);
844 break;
845
846 case ResolveOperation::SkipTopScopeNode:
847 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope_with_top_scope_check);
848 break;
849
850 case ResolveOperation::SkipScopes:
851 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope);
852 break;
853
854 default:
855 break;
856 }
857 LLINT_PROFILE_VALUE(op_resolve_base, result);
858 LLINT_RETURN(result);
6fe7ccc8
A
859}
860
861LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base)
862{
863 LLINT_BEGIN();
93a37866
A
864 ResolveOperations* operations = pc[4].u.resolveOperations;
865 JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations, pc[5].u.putToBaseOperation);
6fe7ccc8
A
866 LLINT_CHECK_EXCEPTION();
867 LLINT_OP(2) = result;
93a37866 868 LLINT_PROFILE_VALUE(op_resolve_with_base, result);
6fe7ccc8
A
869 LLINT_END();
870}
871
872LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this)
873{
874 LLINT_BEGIN();
93a37866
A
875 ResolveOperations* operations = pc[4].u.resolveOperations;
876 JSValue result = JSScope::resolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations);
6fe7ccc8
A
877 LLINT_CHECK_EXCEPTION();
878 LLINT_OP(2) = result;
93a37866
A
879 LLINT_PROFILE_VALUE(op_resolve_with_this, result);
880 LLINT_END();
881}
882
883LLINT_SLOW_PATH_DECL(slow_path_init_global_const_check)
884{
885 LLINT_BEGIN();
886 CodeBlock* codeBlock = exec->codeBlock();
887 symbolTablePut(codeBlock->globalObject(), exec, codeBlock->identifier(pc[4].u.operand), LLINT_OP_C(2).jsValue(), true);
6fe7ccc8
A
888 LLINT_END();
889}
890
891LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
892{
893 LLINT_BEGIN();
894 CodeBlock* codeBlock = exec->codeBlock();
895 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
896 JSValue baseValue = LLINT_OP_C(2).jsValue();
897 PropertySlot slot(baseValue);
898
899 JSValue result = baseValue.get(exec, ident, slot);
900 LLINT_CHECK_EXCEPTION();
901 LLINT_OP(1) = result;
93a37866
A
902
903 if (!LLINT_ALWAYS_ACCESS_SLOW
904 && baseValue.isCell()
6fe7ccc8
A
905 && slot.isCacheable()
906 && slot.slotBase() == baseValue
907 && slot.cachedPropertyType() == PropertySlot::Value) {
908
909 JSCell* baseCell = baseValue.asCell();
910 Structure* structure = baseCell->structure();
911
912 if (!structure->isUncacheableDictionary()
913 && !structure->typeInfo().prohibitsPropertyCaching()) {
914 pc[4].u.structure.set(
93a37866
A
915 vm, codeBlock->ownerExecutable(), structure);
916 if (isInlineOffset(slot.cachedOffset())) {
917 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
918 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
919 } else {
920 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
921 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
922 }
6fe7ccc8
A
923 }
924 }
925
93a37866
A
926 if (!LLINT_ALWAYS_ACCESS_SLOW
927 && isJSArray(baseValue)
928 && ident == exec->propertyNames().length) {
929 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
930#if ENABLE(VALUE_PROFILER)
931 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
932 arrayProfile->observeStructure(baseValue.asCell()->structure());
933 pc[4].u.arrayProfile = arrayProfile;
934#endif
935 }
936
6fe7ccc8
A
937#if ENABLE(VALUE_PROFILER)
938 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
939#endif
940 LLINT_END();
941}
942
943LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
944{
945 LLINT_BEGIN();
946 CodeBlock* codeBlock = exec->codeBlock();
947 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
948 JSValue baseValue = LLINT_OP(2).jsValue();
949 PropertySlot slot(baseValue);
950 LLINT_RETURN(baseValue.get(exec, ident, slot));
951}
952
953LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
954{
955 LLINT_BEGIN();
956 CodeBlock* codeBlock = exec->codeBlock();
957 Identifier& ident = codeBlock->identifier(pc[2].u.operand);
958
959 JSValue baseValue = LLINT_OP_C(1).jsValue();
960 PutPropertySlot slot(codeBlock->isStrictMode());
961 if (pc[8].u.operand)
93a37866 962 asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
6fe7ccc8
A
963 else
964 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
965 LLINT_CHECK_EXCEPTION();
966
93a37866
A
967 if (!LLINT_ALWAYS_ACCESS_SLOW
968 && baseValue.isCell()
6fe7ccc8
A
969 && slot.isCacheable()) {
970
971 JSCell* baseCell = baseValue.asCell();
972 Structure* structure = baseCell->structure();
973
974 if (!structure->isUncacheableDictionary()
975 && !structure->typeInfo().prohibitsPropertyCaching()
976 && baseCell == slot.base()) {
977
978 if (slot.type() == PutPropertySlot::NewProperty) {
93a37866
A
979 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
980 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
981
6fe7ccc8
A
982 // This is needed because some of the methods we call
983 // below may GC.
93a37866
A
984 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
985
986 if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
987 ASSERT(structure->previousID()->isObject());
988 pc[4].u.structure.set(
989 vm, codeBlock->ownerExecutable(), structure->previousID());
990 if (isInlineOffset(slot.cachedOffset()))
991 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
992 else
993 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
994 pc[6].u.structure.set(
995 vm, codeBlock->ownerExecutable(), structure);
996 StructureChain* chain = structure->prototypeChain(exec);
997 ASSERT(chain);
998 pc[7].u.structureChain.set(
999 vm, codeBlock->ownerExecutable(), chain);
6fe7ccc8 1000
93a37866
A
1001 if (pc[8].u.operand) {
1002 if (isInlineOffset(slot.cachedOffset()))
1003 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct);
1004 else
1005 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line);
1006 } else {
1007 if (isInlineOffset(slot.cachedOffset()))
1008 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal);
1009 else
1010 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line);
1011 }
1012 }
6fe7ccc8
A
1013 }
1014 } else {
6fe7ccc8 1015 pc[4].u.structure.set(
93a37866
A
1016 vm, codeBlock->ownerExecutable(), structure);
1017 if (isInlineOffset(slot.cachedOffset())) {
1018 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
1019 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
1020 } else {
1021 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
1022 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
1023 }
6fe7ccc8
A
1024 }
1025 }
1026 }
1027
1028 LLINT_END();
1029}
1030
1031LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
1032{
1033 LLINT_BEGIN();
1034 CodeBlock* codeBlock = exec->codeBlock();
1035 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
1036 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
1037 LLINT_CHECK_EXCEPTION();
1038 if (!couldDelete && codeBlock->isStrictMode())
1039 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1040 LLINT_RETURN(jsBoolean(couldDelete));
1041}
1042
1043inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
1044{
1045 if (LIKELY(baseValue.isCell() && subscript.isString())) {
1046 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
1047 return result;
1048 }
1049
1050 if (subscript.isUInt32()) {
1051 uint32_t i = subscript.asUInt32();
1052 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1053 return asString(baseValue)->getIndex(exec, i);
1054
1055 return baseValue.get(exec, i);
1056 }
93a37866
A
1057
1058 if (isName(subscript))
1059 return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
6fe7ccc8
A
1060
1061 Identifier property(exec, subscript.toString(exec)->value(exec));
1062 return baseValue.get(exec, property);
1063}
1064
1065LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
1066{
1067 LLINT_BEGIN();
1068 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
1069}
1070
1071LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
1072{
1073 LLINT_BEGIN();
1074 JSValue arguments = LLINT_OP(2).jsValue();
1075 if (!arguments) {
93a37866 1076 arguments = Arguments::create(vm, exec);
6fe7ccc8
A
1077 LLINT_CHECK_EXCEPTION();
1078 LLINT_OP(2) = arguments;
1079 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
1080 }
1081
93a37866 1082 LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
6fe7ccc8
A
1083}
1084
1085LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
1086{
1087 LLINT_BEGIN();
1088 LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
1089}
1090
1091LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
1092{
1093 LLINT_BEGIN();
1094
1095 JSValue baseValue = LLINT_OP_C(1).jsValue();
1096 JSValue subscript = LLINT_OP_C(2).jsValue();
1097 JSValue value = LLINT_OP_C(3).jsValue();
1098
1099 if (LIKELY(subscript.isUInt32())) {
1100 uint32_t i = subscript.asUInt32();
93a37866
A
1101 if (baseValue.isObject()) {
1102 JSObject* object = asObject(baseValue);
1103 if (object->canSetIndexQuickly(i))
1104 object->setIndexQuickly(vm, i, value);
6fe7ccc8 1105 else
93a37866 1106 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
6fe7ccc8
A
1107 LLINT_END();
1108 }
1109 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
1110 LLINT_END();
1111 }
93a37866
A
1112
1113 if (isName(subscript)) {
1114 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1115 baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
1116 LLINT_END();
1117 }
1118
6fe7ccc8
A
1119 Identifier property(exec, subscript.toString(exec)->value(exec));
1120 LLINT_CHECK_EXCEPTION();
1121 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1122 baseValue.put(exec, property, value, slot);
1123 LLINT_END();
1124}
1125
1126LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
1127{
1128 LLINT_BEGIN();
1129 JSValue baseValue = LLINT_OP_C(2).jsValue();
1130 JSObject* baseObject = baseValue.toObject(exec);
1131
1132 JSValue subscript = LLINT_OP_C(3).jsValue();
1133
1134 bool couldDelete;
1135
1136 uint32_t i;
1137 if (subscript.getUInt32(i))
1138 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
93a37866
A
1139 else if (isName(subscript))
1140 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
6fe7ccc8
A
1141 else {
1142 LLINT_CHECK_EXCEPTION();
1143 Identifier property(exec, subscript.toString(exec)->value(exec));
1144 LLINT_CHECK_EXCEPTION();
1145 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
1146 }
1147
1148 if (!couldDelete && exec->codeBlock()->isStrictMode())
1149 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1150
1151 LLINT_RETURN(jsBoolean(couldDelete));
1152}
1153
1154LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
1155{
1156 LLINT_BEGIN();
1157 JSValue arrayValue = LLINT_OP_C(1).jsValue();
1158 ASSERT(isJSArray(arrayValue));
93a37866 1159 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
6fe7ccc8
A
1160 LLINT_END();
1161}
1162
1163LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
1164{
1165 LLINT_BEGIN();
1166 ASSERT(LLINT_OP(1).jsValue().isObject());
1167 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1168
1169 GetterSetter* accessor = GetterSetter::create(exec);
1170 LLINT_CHECK_EXCEPTION();
1171
1172 JSValue getter = LLINT_OP(3).jsValue();
1173 JSValue setter = LLINT_OP(4).jsValue();
1174 ASSERT(getter.isObject() || getter.isUndefined());
1175 ASSERT(setter.isObject() || setter.isUndefined());
1176 ASSERT(getter.isObject() || setter.isObject());
1177
1178 if (!getter.isUndefined())
93a37866 1179 accessor->setGetter(vm, asObject(getter));
6fe7ccc8 1180 if (!setter.isUndefined())
93a37866 1181 accessor->setSetter(vm, asObject(setter));
6fe7ccc8 1182 baseObj->putDirectAccessor(
93a37866 1183 exec,
6fe7ccc8
A
1184 exec->codeBlock()->identifier(pc[2].u.operand),
1185 accessor, Accessor);
1186 LLINT_END();
1187}
1188
6fe7ccc8
A
1189LLINT_SLOW_PATH_DECL(slow_path_jtrue)
1190{
1191 LLINT_BEGIN();
1192 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
1193}
1194
1195LLINT_SLOW_PATH_DECL(slow_path_jfalse)
1196{
1197 LLINT_BEGIN();
1198 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
1199}
1200
1201LLINT_SLOW_PATH_DECL(slow_path_jless)
1202{
1203 LLINT_BEGIN();
1204 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1205}
1206
1207LLINT_SLOW_PATH_DECL(slow_path_jnless)
1208{
1209 LLINT_BEGIN();
1210 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1211}
1212
1213LLINT_SLOW_PATH_DECL(slow_path_jgreater)
1214{
1215 LLINT_BEGIN();
1216 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1217}
1218
1219LLINT_SLOW_PATH_DECL(slow_path_jngreater)
1220{
1221 LLINT_BEGIN();
1222 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1223}
1224
1225LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
1226{
1227 LLINT_BEGIN();
1228 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1229}
1230
1231LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
1232{
1233 LLINT_BEGIN();
1234 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1235}
1236
1237LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
1238{
1239 LLINT_BEGIN();
1240 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1241}
1242
1243LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
1244{
1245 LLINT_BEGIN();
1246 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1247}
1248
1249LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
1250{
1251 LLINT_BEGIN();
1252 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1253 ASSERT(scrutinee.isDouble());
1254 double value = scrutinee.asDouble();
1255 int32_t intValue = static_cast<int32_t>(value);
1256 int defaultOffset = pc[2].u.operand;
1257 if (value == intValue) {
1258 CodeBlock* codeBlock = exec->codeBlock();
1259 pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
1260 } else
1261 pc += defaultOffset;
1262 LLINT_END();
1263}
1264
1265LLINT_SLOW_PATH_DECL(slow_path_switch_char)
1266{
1267 LLINT_BEGIN();
1268 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1269 ASSERT(scrutinee.isString());
1270 JSString* string = asString(scrutinee);
1271 ASSERT(string->length() == 1);
1272 int defaultOffset = pc[2].u.operand;
1273 StringImpl* impl = string->value(exec).impl();
1274 CodeBlock* codeBlock = exec->codeBlock();
1275 pc += codeBlock->characterSwitchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
1276 LLINT_END();
1277}
1278
1279LLINT_SLOW_PATH_DECL(slow_path_switch_string)
1280{
1281 LLINT_BEGIN();
1282 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1283 int defaultOffset = pc[2].u.operand;
1284 if (!scrutinee.isString())
1285 pc += defaultOffset;
1286 else {
1287 CodeBlock* codeBlock = exec->codeBlock();
1288 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1289 }
1290 LLINT_END();
1291}
1292
1293LLINT_SLOW_PATH_DECL(slow_path_new_func)
1294{
1295 LLINT_BEGIN();
1296 CodeBlock* codeBlock = exec->codeBlock();
1297 ASSERT(codeBlock->codeType() != FunctionCode
1298 || !codeBlock->needsFullScopeChain()
1299 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
1300#if LLINT_SLOW_PATH_TRACING
93a37866 1301 dataLogF("Creating function!\n");
6fe7ccc8 1302#endif
93a37866 1303 LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
6fe7ccc8
A
1304}
1305
1306LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1307{
1308 LLINT_BEGIN();
1309 CodeBlock* codeBlock = exec->codeBlock();
1310 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
93a37866 1311 JSFunction* func = JSFunction::create(exec, function, exec->scope());
6fe7ccc8
A
1312
1313 LLINT_RETURN(func);
1314}
1315
1316static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1317{
93a37866
A
1318#if LLINT_SLOW_PATH_TRACING
1319 dataLog("Performing host call.\n");
1320#endif
1321
6fe7ccc8 1322 ExecState* exec = execCallee->callerFrame();
93a37866 1323 VM& vm = exec->vm();
6fe7ccc8 1324
93a37866 1325 execCallee->setScope(exec->scope());
6fe7ccc8
A
1326 execCallee->setCodeBlock(0);
1327 execCallee->clearReturnPC();
1328
1329 if (kind == CodeForCall) {
1330 CallData callData;
1331 CallType callType = getCallData(callee, callData);
1332
1333 ASSERT(callType != CallTypeJS);
1334
1335 if (callType == CallTypeHost) {
93a37866 1336 NativeCallFrameTracer tracer(&vm, execCallee);
6fe7ccc8 1337 execCallee->setCallee(asObject(callee));
93a37866 1338 vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
6fe7ccc8 1339
93a37866 1340 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
6fe7ccc8
A
1341 }
1342
1343#if LLINT_SLOW_PATH_TRACING
93a37866 1344 dataLog("Call callee is not a function: ", callee, "\n");
6fe7ccc8
A
1345#endif
1346
1347 ASSERT(callType == CallTypeNone);
1348 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
1349 }
1350
1351 ASSERT(kind == CodeForConstruct);
1352
1353 ConstructData constructData;
1354 ConstructType constructType = getConstructData(callee, constructData);
1355
1356 ASSERT(constructType != ConstructTypeJS);
1357
1358 if (constructType == ConstructTypeHost) {
93a37866 1359 NativeCallFrameTracer tracer(&vm, execCallee);
6fe7ccc8 1360 execCallee->setCallee(asObject(callee));
93a37866 1361 vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
6fe7ccc8 1362
93a37866 1363 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
6fe7ccc8
A
1364 }
1365
1366#if LLINT_SLOW_PATH_TRACING
93a37866 1367 dataLog("Constructor callee is not a function: ", callee, "\n");
6fe7ccc8
A
1368#endif
1369
1370 ASSERT(constructType == ConstructTypeNone);
1371 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
1372}
1373
1374inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1375{
1376#if LLINT_SLOW_PATH_TRACING
93a37866 1377 dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
6fe7ccc8
A
1378#endif
1379
1380 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1381 if (!calleeAsFunctionCell)
1382 return handleHostCall(execCallee, pc, calleeAsValue, kind);
1383
1384 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
93a37866
A
1385 JSScope* scope = callee->scopeUnchecked();
1386 VM& vm = *scope->vm();
1387 execCallee->setScope(scope);
6fe7ccc8
A
1388 ExecutableBase* executable = callee->executable();
1389
1390 MacroAssemblerCodePtr codePtr;
1391 CodeBlock* codeBlock = 0;
1392 if (executable->isHostFunction())
93a37866 1393 codePtr = executable->hostCodeEntryFor(kind);
6fe7ccc8
A
1394 else {
1395 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1396 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1397 if (error)
1398 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1399 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1400 ASSERT(codeBlock);
1401 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
93a37866 1402 codePtr = functionExecutable->jsCodeWithArityCheckEntryFor(kind);
6fe7ccc8 1403 else
93a37866 1404 codePtr = functionExecutable->jsCodeEntryFor(kind);
6fe7ccc8
A
1405 }
1406
93a37866 1407 if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
6fe7ccc8
A
1408 if (callLinkInfo->isOnList())
1409 callLinkInfo->remove();
1410 ExecState* execCaller = execCallee->callerFrame();
93a37866
A
1411 callLinkInfo->callee.set(vm, execCaller->codeBlock()->ownerExecutable(), callee);
1412 callLinkInfo->lastSeenCallee.set(vm, execCaller->codeBlock()->ownerExecutable(), callee);
6fe7ccc8
A
1413 callLinkInfo->machineCodeTarget = codePtr;
1414 if (codeBlock)
1415 codeBlock->linkIncomingCall(callLinkInfo);
1416 }
93a37866 1417
6fe7ccc8
A
1418 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1419}
1420
1421inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1422{
1423 // This needs to:
1424 // - Set up a call frame.
1425 // - Figure out what to call and compile it if necessary.
1426 // - If possible, link the call's inline cache.
1427 // - Return a tuple of machine code address to call and the new call frame.
1428
1429 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1430
1431 ExecState* execCallee = exec + pc[3].u.operand;
1432
1433 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
93a37866 1434 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
6fe7ccc8
A
1435 execCallee->setCallerFrame(exec);
1436
1437 ASSERT(pc[4].u.callLinkInfo);
1438 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
1439}
1440
1441LLINT_SLOW_PATH_DECL(slow_path_call)
1442{
1443 LLINT_BEGIN_NO_SET_PC();
1444 return genericCall(exec, pc, CodeForCall);
1445}
1446
1447LLINT_SLOW_PATH_DECL(slow_path_construct)
1448{
1449 LLINT_BEGIN_NO_SET_PC();
1450 return genericCall(exec, pc, CodeForConstruct);
1451}
1452
1453LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1454{
1455 LLINT_BEGIN();
1456 // This needs to:
1457 // - Set up a call frame while respecting the variable arguments.
1458 // - Figure out what to call and compile it if necessary.
1459 // - Return a tuple of machine code address to call and the new call frame.
1460
1461 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1462
1463 ExecState* execCallee = loadVarargs(
93a37866 1464 exec, &vm.interpreter->stack(),
6fe7ccc8
A
1465 LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
1466 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1467
93a37866 1468 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
6fe7ccc8
A
1469 execCallee->setCallerFrame(exec);
1470 exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs));
1471
1472 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1473}
1474
1475LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1476{
1477 LLINT_BEGIN_NO_SET_PC();
1478 JSValue calleeAsValue = LLINT_OP(1).jsValue();
1479
1480 ExecState* execCallee = exec + pc[3].u.operand;
1481
1482 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1483 execCallee->setCallerFrame(exec);
93a37866
A
1484 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1485 execCallee->setScope(exec->scope());
1486 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
6fe7ccc8
A
1487 execCallee->setCodeBlock(0);
1488 exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_eval));
1489
1490 if (!isHostFunction(calleeAsValue, globalFuncEval))
1491 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1492
93a37866
A
1493 vm.hostCallReturnValue = eval(execCallee);
1494 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
6fe7ccc8
A
1495}
1496
1497LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1498{
1499 LLINT_BEGIN();
1500 ASSERT(exec->codeBlock()->needsFullScopeChain());
93a37866 1501 jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
6fe7ccc8
A
1502 LLINT_END();
1503}
1504
1505LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1506{
1507 LLINT_BEGIN();
93a37866
A
1508 ASSERT(exec->codeBlock()->usesArguments());
1509 Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
1510 if (JSValue activationValue = LLINT_OP_C(2).jsValue())
1511 arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
1512 else
1513 arguments->tearOff(exec);
6fe7ccc8
A
1514 LLINT_END();
1515}
1516
1517LLINT_SLOW_PATH_DECL(slow_path_strcat)
1518{
1519 LLINT_BEGIN();
1520 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1521}
1522
1523LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1524{
1525 LLINT_BEGIN();
1526 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1527}
1528
1529LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1530{
1531 LLINT_BEGIN();
1532 JSValue v = LLINT_OP(2).jsValue();
1533 if (v.isUndefinedOrNull()) {
1534 pc += pc[5].u.operand;
1535 LLINT_END();
1536 }
1537
1538 JSObject* o = v.toObject(exec);
1539 Structure* structure = o->structure();
1540 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1541 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1542 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1543
1544 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1545 LLINT_OP(2) = JSValue(o);
1546 LLINT_OP(3) = Register::withInt(0);
1547 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1548
1549 pc += OPCODE_LENGTH(op_get_pnames);
1550 LLINT_END();
1551}
1552
1553LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1554{
1555 LLINT_BEGIN();
1556 JSObject* base = asObject(LLINT_OP(2).jsValue());
1557 JSString* property = asString(LLINT_OP(1).jsValue());
1558 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1559 // Go to target.
1560 pc += pc[6].u.operand;
1561 } // Else, don't change the PC, so the interpreter will reloop.
1562 LLINT_END();
1563}
1564
93a37866 1565LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
6fe7ccc8
A
1566{
1567 LLINT_BEGIN();
93a37866 1568 JSValue v = LLINT_OP_C(1).jsValue();
6fe7ccc8
A
1569 JSObject* o = v.toObject(exec);
1570 LLINT_CHECK_EXCEPTION();
1571
93a37866 1572 exec->setScope(JSWithScope::create(exec, o));
6fe7ccc8
A
1573
1574 LLINT_END();
1575}
1576
1577LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1578{
1579 LLINT_BEGIN();
93a37866 1580 exec->setScope(exec->scope()->next());
6fe7ccc8
A
1581 LLINT_END();
1582}
1583
93a37866 1584LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
6fe7ccc8
A
1585{
1586 LLINT_BEGIN();
1587 CodeBlock* codeBlock = exec->codeBlock();
93a37866
A
1588 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
1589 exec->setScope(scope);
1590 LLINT_END();
6fe7ccc8
A
1591}
1592
1593LLINT_SLOW_PATH_DECL(slow_path_throw)
1594{
1595 LLINT_BEGIN();
1596 LLINT_THROW(LLINT_OP_C(1).jsValue());
1597}
1598
93a37866 1599LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
6fe7ccc8
A
1600{
1601 LLINT_BEGIN();
93a37866
A
1602 if (pc[2].u.operand)
1603 LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1604 else
1605 LLINT_THROW(createTypeError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1606}
1607
1608LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1609{
1610 LLINT_BEGIN_NO_SET_PC();
1611 if (UNLIKELY(vm.watchdog.didFire(exec)))
1612 LLINT_THROW(createTerminatedExecutionException(&vm));
1613 LLINT_RETURN_TWO(0, exec);
6fe7ccc8
A
1614}
1615
1616LLINT_SLOW_PATH_DECL(slow_path_debug)
1617{
1618 LLINT_BEGIN();
1619 int debugHookID = pc[1].u.operand;
1620 int firstLine = pc[2].u.operand;
1621 int lastLine = pc[3].u.operand;
93a37866
A
1622 int column = pc[4].u.operand;
1623
1624 vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
6fe7ccc8
A
1625
1626 LLINT_END();
1627}
1628
1629LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1630{
1631 LLINT_BEGIN();
93a37866
A
1632 if (LegacyProfiler* profiler = vm.enabledProfiler())
1633 profiler->willExecute(exec, LLINT_OP(1).jsValue());
6fe7ccc8
A
1634 LLINT_END();
1635}
1636
1637LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1638{
1639 LLINT_BEGIN();
93a37866
A
1640 if (LegacyProfiler* profiler = vm.enabledProfiler())
1641 profiler->didExecute(exec, LLINT_OP(1).jsValue());
6fe7ccc8
A
1642 LLINT_END();
1643}
1644
1645LLINT_SLOW_PATH_DECL(throw_from_native_call)
1646{
1647 LLINT_BEGIN();
93a37866 1648 ASSERT(vm.exception);
6fe7ccc8
A
1649 LLINT_END();
1650}
1651
1652} } // namespace JSC::LLInt
1653
1654#endif // ENABLE(LLINT)