2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "LLIntSlowPaths.h"
31 #include "Arguments.h"
32 #include "ArrayConstructor.h"
33 #include "CallFrame.h"
34 #include "CommonSlowPaths.h"
35 #include "GetterSetter.h"
36 #include "HostCallReturnValue.h"
37 #include "Interpreter.h"
39 #include "JITDriver.h"
40 #include "JSActivation.h"
41 #include "JSGlobalObjectFunctions.h"
42 #include "JSNameScope.h"
43 #include "JSPropertyNameIterator.h"
46 #include "JSWithScope.h"
47 #include "LLIntCommon.h"
48 #include "LLIntExceptions.h"
49 #include "LowLevelInterpreter.h"
50 #include "Operations.h"
52 namespace JSC { namespace LLInt {
54 #define LLINT_BEGIN_NO_SET_PC() \
55 JSGlobalData& globalData = exec->globalData(); \
56 NativeCallFrameTracer tracer(&globalData, exec)
59 #define LLINT_SET_PC_FOR_STUBS() do { \
60 exec->codeBlock()->bytecodeOffset(pc); \
61 exec->setCurrentVPC(pc + 1); \
64 #define LLINT_SET_PC_FOR_STUBS() do { \
65 exec->setCurrentVPC(pc + 1); \
69 #define LLINT_BEGIN() \
70 LLINT_BEGIN_NO_SET_PC(); \
71 LLINT_SET_PC_FOR_STUBS()
73 #define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
74 #define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
76 #define LLINT_RETURN_TWO(first, second) do { \
77 return encodeResult(first, second); \
80 #define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
82 #define LLINT_THROW(exceptionToThrow) do { \
83 globalData.exception = (exceptionToThrow); \
84 pc = returnToThrow(exec, pc); \
88 #define LLINT_CHECK_EXCEPTION() do { \
89 if (UNLIKELY(globalData.exception)) { \
90 pc = returnToThrow(exec, pc); \
95 #define LLINT_END() do { \
96 LLINT_CHECK_EXCEPTION(); \
100 #define LLINT_BRANCH(opcode, condition) do { \
101 bool __b_condition = (condition); \
102 LLINT_CHECK_EXCEPTION(); \
104 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
106 pc += OPCODE_LENGTH(opcode); \
110 #define LLINT_RETURN(value) do { \
111 JSValue __r_returnValue = (value); \
112 LLINT_CHECK_EXCEPTION(); \
113 LLINT_OP(1) = __r_returnValue; \
117 #if ENABLE(VALUE_PROFILER)
118 #define LLINT_RETURN_PROFILED(opcode, value) do { \
119 JSValue __rp_returnValue = (value); \
120 LLINT_CHECK_EXCEPTION(); \
121 LLINT_OP(1) = __rp_returnValue; \
122 LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \
126 #define LLINT_PROFILE_VALUE(opcode, value) do { \
127 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
128 JSValue::encode(value); \
131 #else // ENABLE(VALUE_PROFILER)
132 #define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
134 #define LLINT_PROFILE_VALUE(opcode, value) do { } while (false)
136 #endif // ENABLE(VALUE_PROFILER)
138 #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
140 #define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
141 ExecState* __ct_exec = (exec); \
142 Instruction* __ct_pc = (pc); \
143 globalData.exception = (exceptionToThrow); \
144 LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
147 #define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
148 ExecState* __cce_exec = (exec); \
149 Instruction* __cce_pc = (pc); \
150 if (UNLIKELY(globalData.exception)) \
151 LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
154 #define LLINT_CALL_RETURN(exec, pc, callTarget) do { \
155 ExecState* __cr_exec = (exec); \
156 Instruction* __cr_pc = (pc); \
157 void* __cr_callTarget = (callTarget); \
158 LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc); \
159 LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget); \
162 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
165 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
168 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
169 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
172 pc[operand].u.operand);
176 extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
178 JSValue value = LLINT_OP_C(operand).jsValue();
184 EncodedJSValue asValue;
186 u.asValue = JSValue::encode(value);
187 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
190 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
191 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
194 pc[operand].u.operand,
197 value.description());
201 LLINT_SLOW_PATH_DECL(trace_prologue)
203 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
207 static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
209 JSFunction* callee = jsCast<JSFunction*>(exec->callee());
210 FunctionExecutable* executable = callee->jsExecutable();
211 CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
212 dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
213 codeBlock, exec, comment, callee, executable,
214 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
215 exec->callerFrame());
218 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
220 traceFunctionPrologue(exec, "call prologue", CodeForCall);
224 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
226 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
230 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
232 traceFunctionPrologue(exec, "call arity check", CodeForCall);
236 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
238 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
242 LLINT_SLOW_PATH_DECL(trace)
244 dataLogF("%p / %p: executing bc#%zu, %s, scope %p\n",
247 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
248 opcodeNames[exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode)],
250 if (exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
251 dataLogF("Will be returning to %p\n", exec->returnPC().value());
252 dataLogF("The new cfr will be %p\n", exec->callerFrame());
257 LLINT_SLOW_PATH_DECL(special_trace)
259 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
262 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
263 exec->globalData().interpreter->getOpcodeID(pc[0].u.opcode),
264 exec->returnPC().value());
269 inline bool shouldJIT(ExecState* exec)
271 // You can modify this to turn off JITting without rebuilding the world.
272 return exec->globalData().canUseJIT();
275 // Returns true if we should try to OSR.
276 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
278 codeBlock->updateAllValueProfilePredictions();
280 if (!codeBlock->checkIfJITThresholdReached()) {
281 #if ENABLE(JIT_VERBOSE_OSR)
282 dataLogF(" JIT threshold should be lifted.\n");
287 CodeBlock::JITCompilationResult result = codeBlock->jitCompile(exec);
289 case CodeBlock::AlreadyCompiled:
290 #if ENABLE(JIT_VERBOSE_OSR)
291 dataLogF(" Code was already compiled.\n");
293 codeBlock->jitSoon();
295 case CodeBlock::CouldNotCompile:
296 #if ENABLE(JIT_VERBOSE_OSR)
297 dataLogF(" JIT compilation failed.\n");
299 codeBlock->dontJITAnytimeSoon();
301 case CodeBlock::CompiledSuccessfully:
302 #if ENABLE(JIT_VERBOSE_OSR)
303 dataLogF(" JIT compilation successful.\n");
305 codeBlock->jitSoon();
308 ASSERT_NOT_REACHED();
312 enum EntryKind { Prologue, ArityCheck };
313 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
315 #if ENABLE(JIT_VERBOSE_OSR)
316 dataLogF("%p: Entered %s with executeCounter = %s\n", codeBlock, name,
317 codeBlock->llintExecuteCounter().status());
322 if (!shouldJIT(exec)) {
323 codeBlock->dontJITAnytimeSoon();
324 LLINT_RETURN_TWO(0, exec);
326 if (!jitCompileAndSetHeuristics(codeBlock, exec))
327 LLINT_RETURN_TWO(0, exec);
329 if (kind == Prologue)
330 LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
331 ASSERT(kind == ArityCheck);
332 LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
335 LLINT_SLOW_PATH_DECL(entry_osr)
337 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
340 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
342 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
345 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
347 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
350 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
352 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
355 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
357 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
360 LLINT_SLOW_PATH_DECL(loop_osr)
362 CodeBlock* codeBlock = exec->codeBlock();
364 #if ENABLE(JIT_VERBOSE_OSR)
365 dataLogF("%p: Entered loop_osr with executeCounter = %s\n", codeBlock,
366 codeBlock->llintExecuteCounter().status());
369 if (!shouldJIT(exec)) {
370 codeBlock->dontJITAnytimeSoon();
371 LLINT_RETURN_TWO(0, exec);
374 if (!jitCompileAndSetHeuristics(codeBlock, exec))
375 LLINT_RETURN_TWO(0, exec);
377 ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
379 Vector<BytecodeAndMachineOffset> map;
380 codeBlock->jitCodeMap()->decode(map);
381 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned, BytecodeAndMachineOffset::getBytecodeIndex>(map.begin(), map.size(), pc - codeBlock->instructions().begin());
383 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
385 void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
388 LLINT_RETURN_TWO(jumpTarget, exec);
391 LLINT_SLOW_PATH_DECL(replace)
393 CodeBlock* codeBlock = exec->codeBlock();
395 #if ENABLE(JIT_VERBOSE_OSR)
396 dataLogF("%p: Entered replace with executeCounter = %s\n", codeBlock,
397 codeBlock->llintExecuteCounter().status());
401 jitCompileAndSetHeuristics(codeBlock, exec);
403 codeBlock->dontJITAnytimeSoon();
406 #endif // ENABLE(JIT)
408 LLINT_SLOW_PATH_DECL(stack_check)
411 #if LLINT_SLOW_PATH_TRACING
412 dataLogF("Checking stack height with exec = %p.\n", exec);
413 dataLogF("CodeBlock = %p.\n", exec->codeBlock());
414 dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
415 dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
416 dataLogF("Current end is at %p.\n", exec->globalData().interpreter->stack().end());
418 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->stack().end());
419 if (UNLIKELY(!globalData.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
420 ReturnAddressPtr returnPC = exec->returnPC();
421 exec = exec->callerFrame();
422 globalData.exception = createStackOverflowError(exec);
423 interpreterThrowInCaller(exec, returnPC);
424 pc = returnToThrowForThrownException(exec);
429 LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
432 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForCall);
434 ReturnAddressPtr returnPC = exec->returnPC();
435 exec = exec->callerFrame();
436 globalData.exception = createStackOverflowError(exec);
437 interpreterThrowInCaller(exec, returnPC);
438 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
440 LLINT_RETURN_TWO(0, newExec);
443 LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck)
446 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForConstruct);
448 ReturnAddressPtr returnPC = exec->returnPC();
449 exec = exec->callerFrame();
450 globalData.exception = createStackOverflowError(exec);
451 interpreterThrowInCaller(exec, returnPC);
452 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
454 LLINT_RETURN_TWO(0, newExec);
457 LLINT_SLOW_PATH_DECL(slow_path_create_activation)
460 #if LLINT_SLOW_PATH_TRACING
461 dataLogF("Creating an activation, exec = %p!\n", exec);
463 JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock());
464 exec->setScope(activation);
465 LLINT_RETURN(JSValue(activation));
468 LLINT_SLOW_PATH_DECL(slow_path_create_arguments)
471 JSValue arguments = JSValue(Arguments::create(globalData, exec));
472 LLINT_CHECK_EXCEPTION();
473 exec->uncheckedR(pc[1].u.operand) = arguments;
474 exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
478 LLINT_SLOW_PATH_DECL(slow_path_create_this)
481 JSFunction* constructor = jsCast<JSFunction*>(LLINT_OP(2).jsValue().asCell());
484 ConstructData constructData;
485 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
488 Structure* structure = constructor->cachedInheritorID(exec);
489 LLINT_RETURN(constructEmptyObject(exec, structure));
492 LLINT_SLOW_PATH_DECL(slow_path_convert_this)
495 JSValue v1 = LLINT_OP(1).jsValue();
496 ASSERT(v1.isPrimitive());
497 #if ENABLE(VALUE_PROFILER)
498 pc[OPCODE_LENGTH(op_convert_this) - 1].u.profile->m_buckets[0] =
499 JSValue::encode(v1.structureOrUndefined());
501 LLINT_RETURN(v1.toThisObject(exec));
504 LLINT_SLOW_PATH_DECL(slow_path_new_object)
507 LLINT_RETURN(constructEmptyObject(exec));
510 LLINT_SLOW_PATH_DECL(slow_path_new_array)
513 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
516 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
519 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
522 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
525 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
528 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
531 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
532 if (!regExp->isValid())
533 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
534 LLINT_RETURN(RegExpObject::create(globalData, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
537 LLINT_SLOW_PATH_DECL(slow_path_not)
540 LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
543 LLINT_SLOW_PATH_DECL(slow_path_eq)
546 LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
549 LLINT_SLOW_PATH_DECL(slow_path_neq)
552 LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
555 LLINT_SLOW_PATH_DECL(slow_path_stricteq)
558 LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
561 LLINT_SLOW_PATH_DECL(slow_path_nstricteq)
564 LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
567 LLINT_SLOW_PATH_DECL(slow_path_less)
570 LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
573 LLINT_SLOW_PATH_DECL(slow_path_lesseq)
576 LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
579 LLINT_SLOW_PATH_DECL(slow_path_greater)
582 LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
585 LLINT_SLOW_PATH_DECL(slow_path_greatereq)
588 LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
591 LLINT_SLOW_PATH_DECL(slow_path_pre_inc)
594 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
597 LLINT_SLOW_PATH_DECL(slow_path_pre_dec)
600 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
603 LLINT_SLOW_PATH_DECL(slow_path_post_inc)
606 double result = LLINT_OP(2).jsValue().toNumber(exec);
607 LLINT_OP(2) = jsNumber(result + 1);
608 LLINT_RETURN(jsNumber(result));
611 LLINT_SLOW_PATH_DECL(slow_path_post_dec)
614 double result = LLINT_OP(2).jsValue().toNumber(exec);
615 LLINT_OP(2) = jsNumber(result - 1);
616 LLINT_RETURN(jsNumber(result));
619 LLINT_SLOW_PATH_DECL(slow_path_to_jsnumber)
622 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
625 LLINT_SLOW_PATH_DECL(slow_path_negate)
628 LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
631 LLINT_SLOW_PATH_DECL(slow_path_add)
634 JSValue v1 = LLINT_OP_C(2).jsValue();
635 JSValue v2 = LLINT_OP_C(3).jsValue();
637 #if LLINT_SLOW_PATH_TRACING
638 dataLogF("Trying to add %s", v1.description());
639 dataLogF(" to %s.\n", v2.description());
642 if (v1.isString() && !v2.isObject())
643 LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
645 if (v1.isNumber() && v2.isNumber())
646 LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
648 LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
651 // The following arithmetic and bitwise operations need to be sure to run
652 // toNumber() on their operands in order. (A call to toNumber() is idempotent
653 // if an exception is already set on the ExecState.)
655 LLINT_SLOW_PATH_DECL(slow_path_mul)
658 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
659 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
660 LLINT_RETURN(jsNumber(a * b));
663 LLINT_SLOW_PATH_DECL(slow_path_sub)
666 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
667 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
668 LLINT_RETURN(jsNumber(a - b));
671 LLINT_SLOW_PATH_DECL(slow_path_div)
674 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
675 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
676 LLINT_RETURN(jsNumber(a / b));
679 LLINT_SLOW_PATH_DECL(slow_path_mod)
682 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
683 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
684 LLINT_RETURN(jsNumber(fmod(a, b)));
687 LLINT_SLOW_PATH_DECL(slow_path_lshift)
690 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
691 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
692 LLINT_RETURN(jsNumber(a << (b & 31)));
695 LLINT_SLOW_PATH_DECL(slow_path_rshift)
698 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
699 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
700 LLINT_RETURN(jsNumber(a >> (b & 31)));
703 LLINT_SLOW_PATH_DECL(slow_path_urshift)
706 uint32_t a = LLINT_OP_C(2).jsValue().toUInt32(exec);
707 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
708 LLINT_RETURN(jsNumber(a >> (b & 31)));
711 LLINT_SLOW_PATH_DECL(slow_path_bitand)
714 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
715 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
716 LLINT_RETURN(jsNumber(a & b));
719 LLINT_SLOW_PATH_DECL(slow_path_bitor)
722 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
723 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
724 LLINT_RETURN(jsNumber(a | b));
727 LLINT_SLOW_PATH_DECL(slow_path_bitxor)
730 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
731 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
732 LLINT_RETURN(jsNumber(a ^ b));
735 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
739 JSValue value = LLINT_OP_C(2).jsValue();
740 JSValue baseVal = LLINT_OP_C(3).jsValue();
741 if (baseVal.isObject()) {
742 JSObject* baseObject = asObject(baseVal);
743 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
744 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
745 pc += pc[4].u.operand;
746 LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
749 LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
752 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
755 JSValue value = LLINT_OP_C(2).jsValue();
756 JSValue proto = LLINT_OP_C(3).jsValue();
757 ASSERT(!value.isObject() || !proto.isObject());
758 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
761 LLINT_SLOW_PATH_DECL(slow_path_typeof)
764 LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
767 LLINT_SLOW_PATH_DECL(slow_path_is_object)
770 LLINT_RETURN(jsBoolean(jsIsObjectType(exec, LLINT_OP_C(2).jsValue())));
773 LLINT_SLOW_PATH_DECL(slow_path_is_function)
776 LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
779 LLINT_SLOW_PATH_DECL(slow_path_in)
782 LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
785 LLINT_SLOW_PATH_DECL(slow_path_resolve)
788 Identifier ident = exec->codeBlock()->identifier(pc[2].u.operand);
789 ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[3].u.operand);
790 JSValue result = JSScope::resolve(exec, ident, operations);
791 ASSERT(operations->size());
792 ASSERT(operations == exec->codeBlock()->resolveOperations(pc[3].u.operand));
793 switch (operations->data()[0].m_operation) {
794 case ResolveOperation::GetAndReturnGlobalProperty:
795 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_property);
798 case ResolveOperation::GetAndReturnGlobalVar:
799 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_var);
802 case ResolveOperation::SkipTopScopeNode:
803 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_with_top_scope_check);
806 case ResolveOperation::SkipScopes:
807 if (operations->data()[0].m_scopesToSkip)
808 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var);
810 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_on_top_scope);
816 LLINT_RETURN_PROFILED(op_resolve, result);
819 LLINT_SLOW_PATH_DECL(slow_path_put_to_base)
822 PutToBaseOperation* operation = exec->codeBlock()->putToBaseOperation(pc[4].u.operand);
823 JSScope::resolvePut(exec, LLINT_OP_C(1).jsValue(), exec->codeBlock()->identifier(pc[2].u.operand), LLINT_OP_C(3).jsValue(), operation);
824 switch (operation->m_kind) {
825 case PutToBaseOperation::VariablePut:
826 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_to_base_variable);
835 LLINT_SLOW_PATH_DECL(slow_path_resolve_base)
838 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
839 ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand);
841 if (pc[3].u.operand) {
842 result = JSScope::resolveBase(exec, ident, true, operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand));
844 LLINT_THROW(globalData.exception);
846 result = JSScope::resolveBase(exec, ident, false, operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand));
847 ASSERT(operations->size());
848 switch (operations->data()[0].m_operation) {
849 case ResolveOperation::ReturnGlobalObjectAsBase:
850 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_global);
853 case ResolveOperation::SkipTopScopeNode:
854 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope_with_top_scope_check);
857 case ResolveOperation::SkipScopes:
858 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope);
864 LLINT_PROFILE_VALUE(op_resolve_base, result);
865 LLINT_RETURN(result);
868 LLINT_SLOW_PATH_DECL(slow_path_ensure_property_exists)
871 JSObject* object = asObject(LLINT_OP(1).jsValue());
872 PropertySlot slot(object);
873 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
874 if (!object->getPropertySlot(exec, ident, slot))
875 LLINT_THROW(createErrorForInvalidGlobalAssignment(exec, ident.string()));
879 LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base)
882 ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand);
883 JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations, exec->codeBlock()->putToBaseOperation(pc[5].u.operand));
884 LLINT_CHECK_EXCEPTION();
885 LLINT_OP(2) = result;
886 LLINT_PROFILE_VALUE(op_resolve_with_base, result);
890 LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this)
893 ResolveOperations* operations = exec->codeBlock()->resolveOperations(pc[4].u.operand);
894 JSValue result = JSScope::resolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations);
895 LLINT_CHECK_EXCEPTION();
896 LLINT_OP(2) = result;
897 LLINT_PROFILE_VALUE(op_resolve_with_this, result);
901 LLINT_SLOW_PATH_DECL(slow_path_init_global_const_check)
904 CodeBlock* codeBlock = exec->codeBlock();
905 symbolTablePut(codeBlock->globalObject(), exec, codeBlock->identifier(pc[4].u.operand), LLINT_OP_C(2).jsValue(), true);
909 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
912 CodeBlock* codeBlock = exec->codeBlock();
913 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
914 JSValue baseValue = LLINT_OP_C(2).jsValue();
915 PropertySlot slot(baseValue);
917 JSValue result = baseValue.get(exec, ident, slot);
918 LLINT_CHECK_EXCEPTION();
919 LLINT_OP(1) = result;
921 if (!LLINT_ALWAYS_ACCESS_SLOW
922 && baseValue.isCell()
923 && slot.isCacheable()
924 && slot.slotBase() == baseValue
925 && slot.cachedPropertyType() == PropertySlot::Value) {
927 JSCell* baseCell = baseValue.asCell();
928 Structure* structure = baseCell->structure();
930 if (!structure->isUncacheableDictionary()
931 && !structure->typeInfo().prohibitsPropertyCaching()) {
932 pc[4].u.structure.set(
933 globalData, codeBlock->ownerExecutable(), structure);
934 if (isInlineOffset(slot.cachedOffset())) {
935 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
936 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
938 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
939 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
944 if (!LLINT_ALWAYS_ACCESS_SLOW
945 && isJSArray(baseValue)
946 && ident == exec->propertyNames().length) {
947 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
948 #if ENABLE(VALUE_PROFILER)
949 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
950 arrayProfile->observeStructure(baseValue.asCell()->structure());
951 pc[4].u.arrayProfile = arrayProfile;
955 #if ENABLE(VALUE_PROFILER)
956 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
961 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
964 CodeBlock* codeBlock = exec->codeBlock();
965 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
966 JSValue baseValue = LLINT_OP(2).jsValue();
967 PropertySlot slot(baseValue);
968 LLINT_RETURN(baseValue.get(exec, ident, slot));
971 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
974 CodeBlock* codeBlock = exec->codeBlock();
975 Identifier& ident = codeBlock->identifier(pc[2].u.operand);
977 JSValue baseValue = LLINT_OP_C(1).jsValue();
978 PutPropertySlot slot(codeBlock->isStrictMode());
980 asObject(baseValue)->putDirect(globalData, ident, LLINT_OP_C(3).jsValue(), slot);
982 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
983 LLINT_CHECK_EXCEPTION();
985 if (!LLINT_ALWAYS_ACCESS_SLOW
986 && baseValue.isCell()
987 && slot.isCacheable()) {
989 JSCell* baseCell = baseValue.asCell();
990 Structure* structure = baseCell->structure();
992 if (!structure->isUncacheableDictionary()
993 && !structure->typeInfo().prohibitsPropertyCaching()
994 && baseCell == slot.base()) {
996 if (slot.type() == PutPropertySlot::NewProperty) {
997 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
998 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
1000 // This is needed because some of the methods we call
1002 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
1004 if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
1005 ASSERT(structure->previousID()->isObject());
1006 pc[4].u.structure.set(
1007 globalData, codeBlock->ownerExecutable(), structure->previousID());
1008 if (isInlineOffset(slot.cachedOffset()))
1009 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
1011 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
1012 pc[6].u.structure.set(
1013 globalData, codeBlock->ownerExecutable(), structure);
1014 StructureChain* chain = structure->prototypeChain(exec);
1016 pc[7].u.structureChain.set(
1017 globalData, codeBlock->ownerExecutable(), chain);
1019 if (pc[8].u.operand) {
1020 if (isInlineOffset(slot.cachedOffset()))
1021 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct);
1023 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line);
1025 if (isInlineOffset(slot.cachedOffset()))
1026 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal);
1028 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line);
1033 pc[4].u.structure.set(
1034 globalData, codeBlock->ownerExecutable(), structure);
1035 if (isInlineOffset(slot.cachedOffset())) {
1036 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
1037 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
1039 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
1040 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
1049 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
1052 CodeBlock* codeBlock = exec->codeBlock();
1053 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
1054 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
1055 LLINT_CHECK_EXCEPTION();
1056 if (!couldDelete && codeBlock->isStrictMode())
1057 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1058 LLINT_RETURN(jsBoolean(couldDelete));
1061 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
1063 if (LIKELY(baseValue.isCell() && subscript.isString())) {
1064 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
1068 if (subscript.isUInt32()) {
1069 uint32_t i = subscript.asUInt32();
1070 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1071 return asString(baseValue)->getIndex(exec, i);
1073 return baseValue.get(exec, i);
1076 if (isName(subscript))
1077 return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
1079 Identifier property(exec, subscript.toString(exec)->value(exec));
1080 return baseValue.get(exec, property);
1083 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
1086 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
1089 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
1092 JSValue arguments = LLINT_OP(2).jsValue();
1094 arguments = Arguments::create(globalData, exec);
1095 LLINT_CHECK_EXCEPTION();
1096 LLINT_OP(2) = arguments;
1097 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
1100 LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
1103 LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
1106 LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
1109 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
1113 JSValue baseValue = LLINT_OP_C(1).jsValue();
1114 JSValue subscript = LLINT_OP_C(2).jsValue();
1115 JSValue value = LLINT_OP_C(3).jsValue();
1117 if (LIKELY(subscript.isUInt32())) {
1118 uint32_t i = subscript.asUInt32();
1119 if (baseValue.isObject()) {
1120 JSObject* object = asObject(baseValue);
1121 if (object->canSetIndexQuickly(i))
1122 object->setIndexQuickly(globalData, i, value);
1124 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
1127 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
1131 if (isName(subscript)) {
1132 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1133 baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
1137 Identifier property(exec, subscript.toString(exec)->value(exec));
1138 LLINT_CHECK_EXCEPTION();
1139 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1140 baseValue.put(exec, property, value, slot);
1144 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
1147 JSValue baseValue = LLINT_OP_C(2).jsValue();
1148 JSObject* baseObject = baseValue.toObject(exec);
1150 JSValue subscript = LLINT_OP_C(3).jsValue();
1155 if (subscript.getUInt32(i))
1156 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
1157 else if (isName(subscript))
1158 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
1160 LLINT_CHECK_EXCEPTION();
1161 Identifier property(exec, subscript.toString(exec)->value(exec));
1162 LLINT_CHECK_EXCEPTION();
1163 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
1166 if (!couldDelete && exec->codeBlock()->isStrictMode())
1167 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1169 LLINT_RETURN(jsBoolean(couldDelete));
1172 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
1175 JSValue arrayValue = LLINT_OP_C(1).jsValue();
1176 ASSERT(isJSArray(arrayValue));
1177 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
1181 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
1184 ASSERT(LLINT_OP(1).jsValue().isObject());
1185 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1187 GetterSetter* accessor = GetterSetter::create(exec);
1188 LLINT_CHECK_EXCEPTION();
1190 JSValue getter = LLINT_OP(3).jsValue();
1191 JSValue setter = LLINT_OP(4).jsValue();
1192 ASSERT(getter.isObject() || getter.isUndefined());
1193 ASSERT(setter.isObject() || setter.isUndefined());
1194 ASSERT(getter.isObject() || setter.isObject());
1196 if (!getter.isUndefined())
1197 accessor->setGetter(globalData, asObject(getter));
1198 if (!setter.isUndefined())
1199 accessor->setSetter(globalData, asObject(setter));
1200 baseObj->putDirectAccessor(
1202 exec->codeBlock()->identifier(pc[2].u.operand),
1203 accessor, Accessor);
1207 LLINT_SLOW_PATH_DECL(slow_path_jmp_scopes)
1210 unsigned count = pc[1].u.operand;
1211 JSScope* tmp = exec->scope();
1214 exec->setScope(tmp);
1215 pc += pc[2].u.operand;
1219 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
1222 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
1225 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
1228 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
1231 LLINT_SLOW_PATH_DECL(slow_path_jless)
1234 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1237 LLINT_SLOW_PATH_DECL(slow_path_jnless)
1240 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1243 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
1246 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1249 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
1252 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1255 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
1258 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1261 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
1264 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1267 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
1270 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1273 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
1276 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1279 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
1282 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1283 ASSERT(scrutinee.isDouble());
1284 double value = scrutinee.asDouble();
1285 int32_t intValue = static_cast<int32_t>(value);
1286 int defaultOffset = pc[2].u.operand;
1287 if (value == intValue) {
1288 CodeBlock* codeBlock = exec->codeBlock();
1289 pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
1291 pc += defaultOffset;
1295 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
1298 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1299 ASSERT(scrutinee.isString());
1300 JSString* string = asString(scrutinee);
1301 ASSERT(string->length() == 1);
1302 int defaultOffset = pc[2].u.operand;
1303 StringImpl* impl = string->value(exec).impl();
1304 CodeBlock* codeBlock = exec->codeBlock();
1305 pc += codeBlock->characterSwitchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
1309 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
1312 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1313 int defaultOffset = pc[2].u.operand;
1314 if (!scrutinee.isString())
1315 pc += defaultOffset;
1317 CodeBlock* codeBlock = exec->codeBlock();
1318 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1323 LLINT_SLOW_PATH_DECL(slow_path_new_func)
1326 CodeBlock* codeBlock = exec->codeBlock();
1327 ASSERT(codeBlock->codeType() != FunctionCode
1328 || !codeBlock->needsFullScopeChain()
1329 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
1330 #if LLINT_SLOW_PATH_TRACING
1331 dataLogF("Creating function!\n");
1333 LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
1336 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1339 CodeBlock* codeBlock = exec->codeBlock();
1340 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
1341 JSFunction* func = JSFunction::create(exec, function, exec->scope());
1346 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1348 ExecState* exec = execCallee->callerFrame();
1349 JSGlobalData& globalData = exec->globalData();
1351 execCallee->setScope(exec->scope());
1352 execCallee->setCodeBlock(0);
1353 execCallee->clearReturnPC();
1355 if (kind == CodeForCall) {
1357 CallType callType = getCallData(callee, callData);
1359 ASSERT(callType != CallTypeJS);
1361 if (callType == CallTypeHost) {
1362 NativeCallFrameTracer tracer(&globalData, execCallee);
1363 execCallee->setCallee(asObject(callee));
1364 globalData.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1366 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1369 #if LLINT_SLOW_PATH_TRACING
1370 dataLogF("Call callee is not a function: %s\n", callee.description());
1373 ASSERT(callType == CallTypeNone);
1374 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
1377 ASSERT(kind == CodeForConstruct);
1379 ConstructData constructData;
1380 ConstructType constructType = getConstructData(callee, constructData);
1382 ASSERT(constructType != ConstructTypeJS);
1384 if (constructType == ConstructTypeHost) {
1385 NativeCallFrameTracer tracer(&globalData, execCallee);
1386 execCallee->setCallee(asObject(callee));
1387 globalData.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1389 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1392 #if LLINT_SLOW_PATH_TRACING
1393 dataLogF("Constructor callee is not a function: %s\n", callee.description());
1396 ASSERT(constructType == ConstructTypeNone);
1397 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
1400 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1402 #if LLINT_SLOW_PATH_TRACING
1403 dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
1406 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1407 if (!calleeAsFunctionCell)
1408 return handleHostCall(execCallee, pc, calleeAsValue, kind);
1410 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1411 JSScope* scope = callee->scopeUnchecked();
1412 JSGlobalData& globalData = *scope->globalData();
1413 execCallee->setScope(scope);
1414 ExecutableBase* executable = callee->executable();
1416 MacroAssemblerCodePtr codePtr;
1417 CodeBlock* codeBlock = 0;
1418 if (executable->isHostFunction())
1419 codePtr = executable->hostCodeEntryFor(kind);
1421 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1422 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1424 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1425 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1427 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1428 codePtr = functionExecutable->jsCodeWithArityCheckEntryFor(kind);
1430 codePtr = functionExecutable->jsCodeEntryFor(kind);
1434 if (callLinkInfo->isOnList())
1435 callLinkInfo->remove();
1436 ExecState* execCaller = execCallee->callerFrame();
1437 callLinkInfo->callee.set(globalData, execCaller->codeBlock()->ownerExecutable(), callee);
1438 callLinkInfo->lastSeenCallee.set(globalData, execCaller->codeBlock()->ownerExecutable(), callee);
1439 callLinkInfo->machineCodeTarget = codePtr;
1441 codeBlock->linkIncomingCall(callLinkInfo);
1444 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1447 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1450 // - Set up a call frame.
1451 // - Figure out what to call and compile it if necessary.
1452 // - If possible, link the call's inline cache.
1453 // - Return a tuple of machine code address to call and the new call frame.
1455 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1457 ExecState* execCallee = exec + pc[3].u.operand;
1459 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1460 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1461 execCallee->setCallerFrame(exec);
1463 ASSERT(pc[4].u.callLinkInfo);
1464 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
1467 LLINT_SLOW_PATH_DECL(slow_path_call)
1469 LLINT_BEGIN_NO_SET_PC();
1470 return genericCall(exec, pc, CodeForCall);
1473 LLINT_SLOW_PATH_DECL(slow_path_construct)
1475 LLINT_BEGIN_NO_SET_PC();
1476 return genericCall(exec, pc, CodeForConstruct);
1479 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1483 // - Set up a call frame while respecting the variable arguments.
1484 // - Figure out what to call and compile it if necessary.
1485 // - Return a tuple of machine code address to call and the new call frame.
1487 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1489 ExecState* execCallee = loadVarargs(
1490 exec, &globalData.interpreter->stack(),
1491 LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
1492 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1494 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1495 execCallee->setCallerFrame(exec);
1496 exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs));
1498 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1501 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1503 LLINT_BEGIN_NO_SET_PC();
1504 JSValue calleeAsValue = LLINT_OP(1).jsValue();
1506 ExecState* execCallee = exec + pc[3].u.operand;
1508 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1509 execCallee->setCallerFrame(exec);
1510 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1511 execCallee->setScope(exec->scope());
1512 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1513 execCallee->setCodeBlock(0);
1514 exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_eval));
1516 if (!isHostFunction(calleeAsValue, globalFuncEval))
1517 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1519 globalData.hostCallReturnValue = eval(execCallee);
1520 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1523 LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1526 ASSERT(exec->codeBlock()->needsFullScopeChain());
1527 jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(globalData);
1531 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1534 ASSERT(exec->codeBlock()->usesArguments());
1535 Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
1536 if (JSValue activationValue = LLINT_OP_C(2).jsValue())
1537 arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
1539 arguments->tearOff(exec);
1543 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1546 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1549 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1552 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1555 LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1558 JSValue v = LLINT_OP(2).jsValue();
1559 if (v.isUndefinedOrNull()) {
1560 pc += pc[5].u.operand;
1564 JSObject* o = v.toObject(exec);
1565 Structure* structure = o->structure();
1566 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1567 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1568 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1570 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1571 LLINT_OP(2) = JSValue(o);
1572 LLINT_OP(3) = Register::withInt(0);
1573 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1575 pc += OPCODE_LENGTH(op_get_pnames);
1579 LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1582 JSObject* base = asObject(LLINT_OP(2).jsValue());
1583 JSString* property = asString(LLINT_OP(1).jsValue());
1584 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1586 pc += pc[6].u.operand;
1587 } // Else, don't change the PC, so the interpreter will reloop.
1591 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1594 JSValue v = LLINT_OP_C(1).jsValue();
1595 JSObject* o = v.toObject(exec);
1596 LLINT_CHECK_EXCEPTION();
1598 exec->setScope(JSWithScope::create(exec, o));
1603 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1606 exec->setScope(exec->scope()->next());
1610 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1613 CodeBlock* codeBlock = exec->codeBlock();
1614 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
1615 exec->setScope(scope);
1619 LLINT_SLOW_PATH_DECL(slow_path_throw)
1622 LLINT_THROW(LLINT_OP_C(1).jsValue());
1625 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1628 if (pc[2].u.operand)
1629 LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1631 LLINT_THROW(createTypeError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1634 LLINT_SLOW_PATH_DECL(slow_path_debug)
1637 int debugHookID = pc[1].u.operand;
1638 int firstLine = pc[2].u.operand;
1639 int lastLine = pc[3].u.operand;
1640 int column = pc[4].u.operand;
1642 globalData.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
1647 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1650 if (Profiler* profiler = globalData.enabledProfiler())
1651 profiler->willExecute(exec, LLINT_OP(1).jsValue());
1655 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1658 if (Profiler* profiler = globalData.enabledProfiler())
1659 profiler->didExecute(exec, LLINT_OP(1).jsValue());
1663 LLINT_SLOW_PATH_DECL(throw_from_native_call)
1666 ASSERT(globalData.exception);
1670 } } // namespace JSC::LLInt
1672 #endif // ENABLE(LLINT)