2 * Copyright (C) 2011, 2012, 2013, 2014 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"
29 #include "Arguments.h"
30 #include "ArrayConstructor.h"
31 #include "CallFrame.h"
32 #include "CommonSlowPaths.h"
33 #include "CommonSlowPathsExceptions.h"
34 #include "ErrorHandlingScope.h"
35 #include "ExceptionFuzz.h"
36 #include "GetterSetter.h"
37 #include "HostCallReturnValue.h"
38 #include "Interpreter.h"
40 #include "JITExceptions.h"
41 #include "JSLexicalEnvironment.h"
42 #include "JSCInlines.h"
43 #include "JSCJSValue.h"
44 #include "JSGlobalObjectFunctions.h"
45 #include "JSNameScope.h"
46 #include "JSStackInlines.h"
48 #include "JSWithScope.h"
49 #include "LLIntCommon.h"
50 #include "LLIntExceptions.h"
51 #include "LegacyProfiler.h"
52 #include "LowLevelInterpreter.h"
53 #include "ObjectConstructor.h"
54 #include "ProtoCallFrame.h"
55 #include "StructureRareDataInlines.h"
56 #include <wtf/StringPrintStream.h>
58 namespace JSC { namespace LLInt {
60 #define LLINT_BEGIN_NO_SET_PC() \
61 VM& vm = exec->vm(); \
62 NativeCallFrameTracer tracer(&vm, exec)
65 #define LLINT_SET_PC_FOR_STUBS() do { \
66 exec->codeBlock()->bytecodeOffset(pc); \
67 exec->setCurrentVPC(pc + 1); \
70 #define LLINT_SET_PC_FOR_STUBS() do { \
71 exec->setCurrentVPC(pc + 1); \
75 #define LLINT_BEGIN() \
76 LLINT_BEGIN_NO_SET_PC(); \
77 LLINT_SET_PC_FOR_STUBS()
79 #define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
80 #define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
82 #define LLINT_RETURN_TWO(first, second) do { \
83 return encodeResult(first, second); \
86 #define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, 0)
88 #define LLINT_THROW(exceptionToThrow) do { \
89 vm.throwException(exec, exceptionToThrow); \
90 pc = returnToThrow(exec); \
94 #define LLINT_CHECK_EXCEPTION() do { \
95 doExceptionFuzzingIfEnabled(exec, "LLIntSlowPaths", pc); \
96 if (UNLIKELY(vm.exception())) { \
97 pc = returnToThrow(exec); \
102 #define LLINT_END() do { \
103 LLINT_CHECK_EXCEPTION(); \
107 #define LLINT_BRANCH(opcode, condition) do { \
108 bool __b_condition = (condition); \
109 LLINT_CHECK_EXCEPTION(); \
111 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
113 pc += OPCODE_LENGTH(opcode); \
117 #define LLINT_RETURN(value) do { \
118 JSValue __r_returnValue = (value); \
119 LLINT_CHECK_EXCEPTION(); \
120 LLINT_OP(1) = __r_returnValue; \
124 #define LLINT_RETURN_WITH_PC_ADJUSTMENT(value, pcAdjustment) do { \
125 JSValue __r_returnValue = (value); \
126 LLINT_CHECK_EXCEPTION(); \
127 LLINT_OP(1) = __r_returnValue; \
128 pc += (pcAdjustment); \
132 #define LLINT_RETURN_PROFILED(opcode, value) do { \
133 JSValue __rp_returnValue = (value); \
134 LLINT_CHECK_EXCEPTION(); \
135 LLINT_OP(1) = __rp_returnValue; \
136 LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \
140 #define LLINT_PROFILE_VALUE(opcode, value) do { \
141 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
142 JSValue::encode(value); \
145 #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
147 #define LLINT_CALL_THROW(exec, exceptionToThrow) do { \
148 ExecState* __ct_exec = (exec); \
149 vm.throwException(__ct_exec, exceptionToThrow); \
150 LLINT_CALL_END_IMPL(0, callToThrow(__ct_exec)); \
153 #define LLINT_CALL_CHECK_EXCEPTION(exec, execCallee) do { \
154 ExecState* __cce_exec = (exec); \
155 ExecState* __cce_execCallee = (execCallee); \
156 doExceptionFuzzingIfEnabled(__cce_exec, "LLIntSlowPaths/call", nullptr); \
157 if (UNLIKELY(vm.exception())) \
158 LLINT_CALL_END_IMPL(0, callToThrow(__cce_execCallee)); \
161 #define LLINT_CALL_RETURN(exec, execCallee, callTarget) do { \
162 ExecState* __cr_exec = (exec); \
163 ExecState* __cr_execCallee = (execCallee); \
164 void* __cr_callTarget = (callTarget); \
165 LLINT_CALL_CHECK_EXCEPTION(__cr_exec, __cr_execCallee); \
166 LLINT_CALL_END_IMPL(__cr_execCallee, __cr_callTarget); \
169 #define LLINT_RETURN_CALLEE_FRAME(execCallee) do { \
170 ExecState* __rcf_exec = (execCallee); \
171 LLINT_RETURN_TWO(pc, __rcf_exec); \
174 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
177 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
180 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
181 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
184 pc[operand].u.operand);
188 extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
190 JSValue value = LLINT_OP_C(operand).jsValue();
196 EncodedJSValue asValue;
198 u.asValue = JSValue::encode(value);
200 "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
203 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
204 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
207 pc[operand].u.operand,
210 toCString(value).data());
214 LLINT_SLOW_PATH_DECL(trace_prologue)
216 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
220 static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
222 JSFunction* callee = jsCast<JSFunction*>(exec->callee());
223 FunctionExecutable* executable = callee->jsExecutable();
224 CodeBlock* codeBlock = executable->codeBlockFor(kind);
225 dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
226 codeBlock, exec, comment, callee, executable,
227 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
228 exec->callerFrame());
231 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
233 traceFunctionPrologue(exec, "call prologue", CodeForCall);
237 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
239 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
243 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
245 traceFunctionPrologue(exec, "call arity check", CodeForCall);
249 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
251 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
255 LLINT_SLOW_PATH_DECL(trace)
257 dataLogF("%p / %p: executing bc#%zu, %s, scope %p, pc = %p\n",
260 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
261 opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
262 exec->uncheckedR(exec->codeBlock()->scopeRegister().offset()).Register::scope(), pc);
263 if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_enter) {
264 dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
265 *bitwise_cast<volatile char*>(exec->returnPC().value());
267 if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
268 dataLogF("Will be returning to %p\n", exec->returnPC().value());
269 dataLogF("The new cfr will be %p\n", exec->callerFrame());
274 LLINT_SLOW_PATH_DECL(special_trace)
276 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
279 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
280 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
281 exec->returnPC().value());
285 enum EntryKind { Prologue, ArityCheck };
288 inline bool shouldJIT(ExecState* exec)
290 // You can modify this to turn off JITting without rebuilding the world.
291 return exec->vm().canUseJIT();
294 // Returns true if we should try to OSR.
295 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
298 DeferGCForAWhile deferGC(vm.heap); // My callers don't set top callframe, so we don't want to GC here at all.
300 codeBlock->updateAllValueProfilePredictions();
302 if (!codeBlock->checkIfJITThresholdReached()) {
303 if (Options::verboseOSR())
304 dataLogF(" JIT threshold should be lifted.\n");
308 switch (codeBlock->jitType()) {
309 case JITCode::BaselineJIT: {
310 if (Options::verboseOSR())
311 dataLogF(" Code was already compiled.\n");
312 codeBlock->jitSoon();
315 case JITCode::InterpreterThunk: {
316 CompilationResult result = JIT::compile(&vm, codeBlock, JITCompilationCanFail);
318 case CompilationFailed:
319 if (Options::verboseOSR())
320 dataLogF(" JIT compilation failed.\n");
321 codeBlock->dontJITAnytimeSoon();
323 case CompilationSuccessful:
324 if (Options::verboseOSR())
325 dataLogF(" JIT compilation successful.\n");
326 codeBlock->install();
327 codeBlock->jitSoon();
330 RELEASE_ASSERT_NOT_REACHED();
335 RELEASE_ASSERT_NOT_REACHED();
340 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
342 if (Options::verboseOSR()) {
344 *codeBlock, ": Entered ", name, " with executeCounter = ",
345 codeBlock->llintExecuteCounter(), "\n");
348 if (!shouldJIT(exec)) {
349 codeBlock->dontJITAnytimeSoon();
350 LLINT_RETURN_TWO(0, 0);
352 if (!jitCompileAndSetHeuristics(codeBlock, exec))
353 LLINT_RETURN_TWO(0, 0);
355 if (kind == Prologue)
356 LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), 0);
357 ASSERT(kind == ArityCheck);
358 LLINT_RETURN_TWO(codeBlock->jitCode()->addressForCall(
359 *codeBlock->vm(), codeBlock->ownerExecutable(), MustCheckArity,
360 RegisterPreservationNotRequired).executableAddress(), 0);
363 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char*, EntryKind)
365 codeBlock->dontJITAnytimeSoon();
366 LLINT_RETURN_TWO(0, exec);
368 #endif // ENABLE(JIT)
370 LLINT_SLOW_PATH_DECL(entry_osr)
372 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
375 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
377 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForCall(), "entry_osr_function_for_call", Prologue);
380 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
382 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForConstruct(), "entry_osr_function_for_construct", Prologue);
385 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
387 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForCall(), "entry_osr_function_for_call_arityCheck", ArityCheck);
390 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
392 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForConstruct(), "entry_osr_function_for_construct_arityCheck", ArityCheck);
395 LLINT_SLOW_PATH_DECL(loop_osr)
397 CodeBlock* codeBlock = exec->codeBlock();
400 if (Options::verboseOSR()) {
402 *codeBlock, ": Entered loop_osr with executeCounter = ",
403 codeBlock->llintExecuteCounter(), "\n");
406 if (!shouldJIT(exec)) {
407 codeBlock->dontJITAnytimeSoon();
408 LLINT_RETURN_TWO(0, 0);
411 if (!jitCompileAndSetHeuristics(codeBlock, exec))
412 LLINT_RETURN_TWO(0, 0);
414 ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
416 Vector<BytecodeAndMachineOffset> map;
417 codeBlock->jitCodeMap()->decode(map);
418 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
420 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
422 void* jumpTarget = codeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
425 LLINT_RETURN_TWO(jumpTarget, exec->topOfFrame());
428 codeBlock->dontJITAnytimeSoon();
429 LLINT_RETURN_TWO(0, 0);
430 #endif // ENABLE(JIT)
433 LLINT_SLOW_PATH_DECL(replace)
435 CodeBlock* codeBlock = exec->codeBlock();
438 if (Options::verboseOSR()) {
440 *codeBlock, ": Entered replace with executeCounter = ",
441 codeBlock->llintExecuteCounter(), "\n");
445 jitCompileAndSetHeuristics(codeBlock, exec);
447 codeBlock->dontJITAnytimeSoon();
450 codeBlock->dontJITAnytimeSoon();
452 #endif // ENABLE(JIT)
455 LLINT_SLOW_PATH_DECL(stack_check)
458 #if LLINT_SLOW_PATH_TRACING
459 dataLogF("Checking stack height with exec = %p.\n", exec);
460 dataLogF("CodeBlock = %p.\n", exec->codeBlock());
461 dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
462 dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
464 #if ENABLE(LLINT_C_LOOP)
465 dataLogF("Current end is at %p.\n", exec->vm().jsStackLimit());
467 dataLogF("Current end is at %p.\n", exec->vm().stackLimit());
471 // This stack check is done in the prologue for a function call, and the
472 // CallFrame is not completely set up yet. For example, if the frame needs
473 // a lexical environment object, the lexical environment object will only be
474 // set up after we start executing the function. If we need to throw a
475 // StackOverflowError here, then we need to tell the prologue to start the
476 // stack unwinding from the caller frame (which is fully set up) instead.
477 // To do that, we return the caller's CallFrame in the second return value.
479 // If the stack check succeeds and we don't need to throw the error, then
480 // we'll return 0 instead. The prologue will check for a non-zero value
481 // when determining whether to set the callFrame or not.
483 // For JIT enabled builds which uses the C stack, the stack is not growable.
484 // Hence, if we get here, then we know a stack overflow is imminent. So, just
485 // throw the StackOverflowError unconditionally.
487 ASSERT(!vm.interpreter->stack().containsAddress(exec->topOfFrame()));
488 if (LIKELY(vm.interpreter->stack().ensureCapacityFor(exec->topOfFrame())))
489 LLINT_RETURN_TWO(pc, 0);
492 exec = exec->callerFrame();
493 vm.topCallFrame = exec;
494 ErrorHandlingScope errorScope(vm);
495 CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
496 pc = returnToThrowForThrownException(exec);
497 LLINT_RETURN_TWO(pc, exec);
500 LLINT_SLOW_PATH_DECL(slow_path_create_lexical_environment)
503 #if LLINT_SLOW_PATH_TRACING
504 dataLogF("Creating an lexicalEnvironment, exec = %p!\n", exec);
506 int scopeReg = pc[2].u.operand;
507 JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
508 JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, scope, exec->codeBlock());
509 exec->uncheckedR(pc[2].u.operand) = lexicalEnvironment;
510 LLINT_RETURN(JSValue(lexicalEnvironment));
513 LLINT_SLOW_PATH_DECL(slow_path_new_object)
516 LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
519 LLINT_SLOW_PATH_DECL(slow_path_new_array)
522 LLINT_RETURN(constructArrayNegativeIndexed(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
525 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
528 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
531 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
534 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
537 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
540 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
541 if (!regExp->isValid())
542 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
543 LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regExp));
546 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
550 JSValue value = LLINT_OP_C(2).jsValue();
551 JSValue baseVal = LLINT_OP_C(3).jsValue();
552 if (baseVal.isObject()) {
553 JSObject* baseObject = asObject(baseVal);
554 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
555 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
556 JSValue result = jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value));
557 LLINT_RETURN_WITH_PC_ADJUSTMENT(result, pc[4].u.operand);
560 LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
563 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
566 JSValue value = LLINT_OP_C(2).jsValue();
567 JSValue proto = LLINT_OP_C(3).jsValue();
568 ASSERT(!value.isObject() || !proto.isObject());
569 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
572 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
575 CodeBlock* codeBlock = exec->codeBlock();
576 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
577 JSValue baseValue = LLINT_OP_C(2).jsValue();
578 PropertySlot slot(baseValue);
580 JSValue result = baseValue.get(exec, ident, slot);
581 LLINT_CHECK_EXCEPTION();
582 LLINT_OP(1) = result;
584 if (!LLINT_ALWAYS_ACCESS_SLOW
585 && baseValue.isCell()
586 && slot.isCacheable()
587 && slot.slotBase() == baseValue
588 && slot.isCacheableValue()) {
590 JSCell* baseCell = baseValue.asCell();
591 Structure* structure = baseCell->structure();
593 if (!structure->isUncacheableDictionary()
594 && !structure->typeInfo().prohibitsPropertyCaching()
595 && !structure->typeInfo().newImpurePropertyFiresWatchpoints()) {
596 ConcurrentJITLocker locker(codeBlock->m_lock);
598 pc[4].u.structure.set(
599 vm, codeBlock->ownerExecutable(), structure);
600 if (isInlineOffset(slot.cachedOffset())) {
601 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
602 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
604 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_out_of_line);
605 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
610 if (!LLINT_ALWAYS_ACCESS_SLOW
611 && isJSArray(baseValue)
612 && ident == exec->propertyNames().length) {
613 pc[0].u.opcode = LLInt::getOpcode(op_get_array_length);
614 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
615 arrayProfile->observeStructure(baseValue.asCell()->structure());
616 pc[4].u.arrayProfile = arrayProfile;
619 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
623 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
626 CodeBlock* codeBlock = exec->codeBlock();
627 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
628 JSValue baseValue = LLINT_OP(2).jsValue();
629 PropertySlot slot(baseValue);
630 LLINT_RETURN(baseValue.get(exec, ident, slot));
633 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
636 CodeBlock* codeBlock = exec->codeBlock();
637 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
639 JSValue baseValue = LLINT_OP_C(1).jsValue();
640 PutPropertySlot slot(baseValue, codeBlock->isStrictMode(), codeBlock->putByIdContext());
642 asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
644 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
645 LLINT_CHECK_EXCEPTION();
647 if (!LLINT_ALWAYS_ACCESS_SLOW
648 && baseValue.isCell()
649 && slot.isCacheablePut()) {
651 JSCell* baseCell = baseValue.asCell();
652 Structure* structure = baseCell->structure();
654 if (!structure->isUncacheableDictionary()
655 && !structure->typeInfo().prohibitsPropertyCaching()
656 && baseCell == slot.base()) {
658 if (slot.type() == PutPropertySlot::NewProperty) {
659 GCSafeConcurrentJITLocker locker(codeBlock->m_lock, vm.heap);
661 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
662 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
664 // This is needed because some of the methods we call
666 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
668 if (normalizePrototypeChain(exec, structure) != InvalidPrototypeChain) {
669 ASSERT(structure->previousID()->isObject());
670 pc[4].u.structure.set(
671 vm, codeBlock->ownerExecutable(), structure->previousID());
672 if (isInlineOffset(slot.cachedOffset()))
673 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
675 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
676 pc[6].u.structure.set(
677 vm, codeBlock->ownerExecutable(), structure);
678 StructureChain* chain = structure->prototypeChain(exec);
680 pc[7].u.structureChain.set(
681 vm, codeBlock->ownerExecutable(), chain);
683 if (pc[8].u.operand) {
684 if (isInlineOffset(slot.cachedOffset()))
685 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct);
687 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct_out_of_line);
689 if (isInlineOffset(slot.cachedOffset()))
690 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal);
692 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal_out_of_line);
697 structure->didCachePropertyReplacement(vm, slot.cachedOffset());
698 pc[4].u.structure.set(
699 vm, codeBlock->ownerExecutable(), structure);
700 if (isInlineOffset(slot.cachedOffset())) {
701 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
702 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
704 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_out_of_line);
705 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
714 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
717 CodeBlock* codeBlock = exec->codeBlock();
718 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
719 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
720 LLINT_CHECK_EXCEPTION();
721 if (!couldDelete && codeBlock->isStrictMode())
722 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
723 LLINT_RETURN(jsBoolean(couldDelete));
726 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
728 if (LIKELY(baseValue.isCell() && subscript.isString())) {
730 Structure& structure = *baseValue.asCell()->structure(vm);
731 if (JSCell::canUseFastGetOwnProperty(structure)) {
732 if (AtomicStringImpl* existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
733 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString))
739 if (subscript.isUInt32()) {
740 uint32_t i = subscript.asUInt32();
741 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
742 return asString(baseValue)->getIndex(exec, i);
744 return baseValue.get(exec, i);
747 if (isName(subscript))
748 return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
750 Identifier property = subscript.toString(exec)->toIdentifier(exec);
751 return baseValue.get(exec, property);
754 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
757 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
760 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
763 JSValue arguments = LLINT_OP(2).jsValue();
765 int lexicalEnvironmentReg = pc[4].u.operand;
766 JSLexicalEnvironment* lexicalEnvironment = VirtualRegister(lexicalEnvironmentReg).isValid() ?
767 exec->uncheckedR(lexicalEnvironmentReg).lexicalEnvironment() : nullptr;
768 arguments = JSValue(Arguments::create(vm, exec, lexicalEnvironment));
770 LLINT_CHECK_EXCEPTION();
771 LLINT_OP(2) = arguments;
772 exec->uncheckedR(unmodifiedArgumentsRegister(VirtualRegister(pc[2].u.operand)).offset()) = arguments;
775 LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
778 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
782 JSValue baseValue = LLINT_OP_C(1).jsValue();
783 JSValue subscript = LLINT_OP_C(2).jsValue();
784 JSValue value = LLINT_OP_C(3).jsValue();
786 if (LIKELY(subscript.isUInt32())) {
787 uint32_t i = subscript.asUInt32();
788 if (baseValue.isObject()) {
789 JSObject* object = asObject(baseValue);
790 if (object->canSetIndexQuickly(i))
791 object->setIndexQuickly(vm, i, value);
793 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
796 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
800 if (isName(subscript)) {
801 PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
802 baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
806 Identifier property = subscript.toString(exec)->toIdentifier(exec);
807 LLINT_CHECK_EXCEPTION();
808 PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
809 baseValue.put(exec, property, value, slot);
813 LLINT_SLOW_PATH_DECL(slow_path_put_by_val_direct)
817 JSValue baseValue = LLINT_OP_C(1).jsValue();
818 JSValue subscript = LLINT_OP_C(2).jsValue();
819 JSValue value = LLINT_OP_C(3).jsValue();
820 RELEASE_ASSERT(baseValue.isObject());
821 JSObject* baseObject = asObject(baseValue);
822 if (LIKELY(subscript.isUInt32())) {
823 uint32_t i = subscript.asUInt32();
824 baseObject->putDirectIndex(exec, i, value);
825 } else if (isName(subscript)) {
826 PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
827 baseObject->putDirect(exec->vm(), jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
829 Identifier property = subscript.toString(exec)->toIdentifier(exec);
830 if (!exec->vm().exception()) { // Don't put to an object if toString threw an exception.
831 PutPropertySlot slot(baseObject, exec->codeBlock()->isStrictMode());
832 baseObject->putDirect(exec->vm(), property, value, slot);
838 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
841 JSValue baseValue = LLINT_OP_C(2).jsValue();
842 JSObject* baseObject = baseValue.toObject(exec);
844 JSValue subscript = LLINT_OP_C(3).jsValue();
849 if (subscript.getUInt32(i))
850 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
851 else if (isName(subscript))
852 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
854 LLINT_CHECK_EXCEPTION();
855 Identifier property = subscript.toString(exec)->toIdentifier(exec);
856 LLINT_CHECK_EXCEPTION();
857 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
860 if (!couldDelete && exec->codeBlock()->isStrictMode())
861 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
863 LLINT_RETURN(jsBoolean(couldDelete));
866 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
869 JSValue arrayValue = LLINT_OP_C(1).jsValue();
870 ASSERT(isJSArray(arrayValue));
871 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
875 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
878 ASSERT(LLINT_OP(1).jsValue().isObject());
879 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
881 GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
882 LLINT_CHECK_EXCEPTION();
884 JSValue getter = LLINT_OP(3).jsValue();
885 JSValue setter = LLINT_OP(4).jsValue();
886 ASSERT(getter.isObject() || getter.isUndefined());
887 ASSERT(setter.isObject() || setter.isUndefined());
888 ASSERT(getter.isObject() || setter.isObject());
890 if (!getter.isUndefined())
891 accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
892 if (!setter.isUndefined())
893 accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
894 baseObj->putDirectAccessor(
896 exec->codeBlock()->identifier(pc[2].u.operand),
901 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
904 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
907 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
910 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
913 LLINT_SLOW_PATH_DECL(slow_path_jless)
916 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
919 LLINT_SLOW_PATH_DECL(slow_path_jnless)
922 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
925 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
928 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
931 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
934 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
937 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
940 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
943 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
946 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
949 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
952 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
955 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
958 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
961 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
964 JSValue scrutinee = LLINT_OP_C(3).jsValue();
965 ASSERT(scrutinee.isDouble());
966 double value = scrutinee.asDouble();
967 int32_t intValue = static_cast<int32_t>(value);
968 int defaultOffset = pc[2].u.operand;
969 if (value == intValue) {
970 CodeBlock* codeBlock = exec->codeBlock();
971 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
977 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
980 JSValue scrutinee = LLINT_OP_C(3).jsValue();
981 ASSERT(scrutinee.isString());
982 JSString* string = asString(scrutinee);
983 ASSERT(string->length() == 1);
984 int defaultOffset = pc[2].u.operand;
985 StringImpl* impl = string->value(exec).impl();
986 CodeBlock* codeBlock = exec->codeBlock();
987 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
991 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
994 JSValue scrutinee = LLINT_OP_C(3).jsValue();
995 int defaultOffset = pc[2].u.operand;
996 if (!scrutinee.isString())
999 CodeBlock* codeBlock = exec->codeBlock();
1000 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1005 LLINT_SLOW_PATH_DECL(slow_path_new_func)
1008 CodeBlock* codeBlock = exec->codeBlock();
1009 ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation());
1010 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1011 #if LLINT_SLOW_PATH_TRACING
1012 dataLogF("Creating function!\n");
1014 LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
1017 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1020 CodeBlock* codeBlock = exec->codeBlock();
1021 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1022 FunctionExecutable* function = codeBlock->functionExpr(pc[3].u.operand);
1023 JSFunction* func = JSFunction::create(vm, function, scope);
1028 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1032 #if LLINT_SLOW_PATH_TRACING
1033 dataLog("Performing host call.\n");
1036 ExecState* exec = execCallee->callerFrame();
1037 VM& vm = exec->vm();
1039 execCallee->setCodeBlock(0);
1040 execCallee->clearReturnPC();
1042 if (kind == CodeForCall) {
1044 CallType callType = getCallData(callee, callData);
1046 ASSERT(callType != CallTypeJS);
1048 if (callType == CallTypeHost) {
1049 NativeCallFrameTracer tracer(&vm, execCallee);
1050 execCallee->setCallee(asObject(callee));
1051 vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1053 LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1056 #if LLINT_SLOW_PATH_TRACING
1057 dataLog("Call callee is not a function: ", callee, "\n");
1060 ASSERT(callType == CallTypeNone);
1061 LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
1064 ASSERT(kind == CodeForConstruct);
1066 ConstructData constructData;
1067 ConstructType constructType = getConstructData(callee, constructData);
1069 ASSERT(constructType != ConstructTypeJS);
1071 if (constructType == ConstructTypeHost) {
1072 NativeCallFrameTracer tracer(&vm, execCallee);
1073 execCallee->setCallee(asObject(callee));
1074 vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1076 LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1079 #if LLINT_SLOW_PATH_TRACING
1080 dataLog("Constructor callee is not a function: ", callee, "\n");
1083 ASSERT(constructType == ConstructTypeNone);
1084 LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1087 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1089 ExecState* exec = execCallee->callerFrame();
1091 #if LLINT_SLOW_PATH_TRACING
1092 dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
1095 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1096 if (!calleeAsFunctionCell)
1097 return handleHostCall(execCallee, pc, calleeAsValue, kind);
1099 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1100 JSScope* scope = callee->scopeUnchecked();
1101 VM& vm = *scope->vm();
1102 ExecutableBase* executable = callee->executable();
1104 MacroAssemblerCodePtr codePtr;
1105 CodeBlock* codeBlock = 0;
1106 if (executable->isHostFunction())
1107 codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
1109 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1110 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, &scope, kind);
1112 LLINT_CALL_THROW(exec, error);
1113 codeBlock = functionExecutable->codeBlockFor(kind);
1115 ArityCheckMode arity;
1116 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1117 arity = MustCheckArity;
1119 arity = ArityCheckNotRequired;
1120 codePtr = functionExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
1125 if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1126 CodeBlock* callerCodeBlock = exec->codeBlock();
1128 ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1130 if (callLinkInfo->isOnList())
1131 callLinkInfo->remove();
1132 callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1133 callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1134 callLinkInfo->machineCodeTarget = codePtr;
1136 codeBlock->linkIncomingCall(exec, callLinkInfo);
1139 LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
1142 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1145 // - Set up a call frame.
1146 // - Figure out what to call and compile it if necessary.
1147 // - If possible, link the call's inline cache.
1148 // - Return a tuple of machine code address to call and the new call frame.
1150 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1152 ExecState* execCallee = exec - pc[4].u.operand;
1154 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1155 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1156 execCallee->setCallerFrame(exec);
1158 ASSERT(pc[5].u.callLinkInfo);
1159 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1162 LLINT_SLOW_PATH_DECL(slow_path_call)
1164 LLINT_BEGIN_NO_SET_PC();
1165 return genericCall(exec, pc, CodeForCall);
1168 LLINT_SLOW_PATH_DECL(slow_path_construct)
1170 LLINT_BEGIN_NO_SET_PC();
1171 return genericCall(exec, pc, CodeForConstruct);
1174 LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_varargs)
1178 // - Set up a call frame while respecting the variable arguments.
1180 ExecState* execCallee = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
1181 LLINT_OP_C(4).jsValue(), pc[5].u.operand, pc[6].u.operand);
1182 LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1184 vm.newCallFrameReturnValue = execCallee;
1186 LLINT_RETURN_CALLEE_FRAME(execCallee);
1189 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1191 LLINT_BEGIN_NO_SET_PC();
1193 // - Figure out what to call and compile it if necessary.
1194 // - Return a tuple of machine code address to call and the new call frame.
1196 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1198 ExecState* execCallee = vm.newCallFrameReturnValue;
1200 loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
1201 LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1203 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1204 execCallee->setCallerFrame(exec);
1205 exec->setCurrentVPC(pc);
1207 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1210 LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
1212 LLINT_BEGIN_NO_SET_PC();
1214 // - Figure out what to call and compile it if necessary.
1215 // - Return a tuple of machine code address to call and the new call frame.
1217 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1219 ExecState* execCallee = vm.newCallFrameReturnValue;
1221 loadVarargs(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand);
1222 LLINT_CALL_CHECK_EXCEPTION(exec, exec);
1224 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1225 execCallee->setCallerFrame(exec);
1226 exec->setCurrentVPC(pc);
1228 return setUpCall(execCallee, pc, CodeForConstruct, calleeAsValue);
1231 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1233 LLINT_BEGIN_NO_SET_PC();
1234 JSValue calleeAsValue = LLINT_OP(2).jsValue();
1236 ExecState* execCallee = exec - pc[4].u.operand;
1238 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1239 execCallee->setCallerFrame(exec);
1240 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1241 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1242 execCallee->setCodeBlock(0);
1243 exec->setCurrentVPC(pc);
1245 if (!isHostFunction(calleeAsValue, globalFuncEval))
1246 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1248 vm.hostCallReturnValue = eval(execCallee);
1249 LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
1252 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1255 ASSERT(exec->codeBlock()->usesArguments());
1256 Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(VirtualRegister(pc[1].u.operand).offset()).jsValue());
1257 arguments->tearOff(exec);
1261 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1264 LLINT_RETURN(jsStringFromRegisterArray(exec, &LLINT_OP(2), pc[3].u.operand));
1267 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1270 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1273 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1276 JSValue v = LLINT_OP_C(2).jsValue();
1277 JSObject* o = v.toObject(exec);
1278 LLINT_CHECK_EXCEPTION();
1280 int scopeReg = pc[1].u.operand;
1281 JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
1282 exec->uncheckedR(scopeReg) = JSWithScope::create(exec, o, currentScope);
1287 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1290 int scopeReg = pc[1].u.operand;
1291 JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1292 exec->uncheckedR(scopeReg) = scope->next();
1296 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1299 CodeBlock* codeBlock = exec->codeBlock();
1300 int scopeReg = pc[1].u.operand;
1301 JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
1302 JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[5].u.operand);
1303 JSNameScope* scope = JSNameScope::create(exec, currentScope, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
1304 exec->uncheckedR(scopeReg) = scope;
1308 LLINT_SLOW_PATH_DECL(slow_path_throw)
1311 LLINT_THROW(LLINT_OP_C(1).jsValue());
1314 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1317 if (pc[2].u.operand)
1318 LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1320 LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1323 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1325 LLINT_BEGIN_NO_SET_PC();
1326 ASSERT(vm.watchdog);
1327 if (UNLIKELY(vm.watchdog->didFire(exec)))
1328 LLINT_THROW(createTerminatedExecutionException(&vm));
1329 LLINT_RETURN_TWO(0, exec);
1332 LLINT_SLOW_PATH_DECL(slow_path_debug)
1335 int debugHookID = pc[1].u.operand;
1336 vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID));
1341 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1344 if (LegacyProfiler* profiler = vm.enabledProfiler())
1345 profiler->willExecute(exec, LLINT_OP(1).jsValue());
1349 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1352 if (LegacyProfiler* profiler = vm.enabledProfiler())
1353 profiler->didExecute(exec, LLINT_OP(1).jsValue());
1357 LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
1359 LLINT_BEGIN_NO_SET_PC();
1360 ASSERT(vm.exception());
1361 genericUnwind(&vm, exec, vm.exception());
1365 LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
1368 const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1369 JSScope* scope = LLINT_OP(2).Register::scope();
1370 LLINT_RETURN(JSScope::resolve(exec, scope, ident));
1373 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1377 const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1378 JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1379 ResolveModeAndType modeAndType(pc[4].u.operand);
1381 PropertySlot slot(scope);
1382 if (!scope->getPropertySlot(exec, ident, slot)) {
1383 if (modeAndType.mode() == ThrowIfNotFound)
1384 LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1385 LLINT_RETURN(jsUndefined());
1388 // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1389 if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1390 if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1391 CodeBlock* codeBlock = exec->codeBlock();
1392 Structure* structure = scope->structure(vm);
1394 ConcurrentJITLocker locker(codeBlock->m_lock);
1395 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
1396 pc[6].u.operand = slot.cachedOffset();
1398 structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
1402 LLINT_RETURN(slot.getValue(exec, ident));
1405 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1409 CodeBlock* codeBlock = exec->codeBlock();
1410 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1411 JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1412 JSValue value = LLINT_OP_C(3).jsValue();
1413 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1414 if (modeAndType.type() == LocalClosureVar) {
1415 JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1416 environment->registerAt(pc[6].u.operand).set(vm, environment, value);
1417 if (VariableWatchpointSet* set = pc[5].u.watchpointSet)
1418 set->notifyWrite(vm, value, "Executed op_put_scope<LocalClosureVar>");
1422 if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
1423 LLINT_THROW(createUndefinedVariableError(exec, ident));
1425 PutPropertySlot slot(scope, codeBlock->isStrictMode());
1426 scope->methodTable()->put(scope, exec, ident, value, slot);
1428 CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
1433 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
1435 ExecState* exec = vm->topCallFrame;
1437 exec = protoFrame->callee()->globalObject()->globalExec();
1438 throwStackOverflowError(exec);
1439 return encodeResult(0, 0);
1443 extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM* vm, Register* newTopOfStack)
1445 bool success = vm->interpreter->stack().ensureCapacityFor(newTopOfStack);
1446 return encodeResult(reinterpret_cast<void*>(success), 0);
1450 extern "C" void llint_write_barrier_slow(ExecState* exec, JSCell* cell)
1452 VM& vm = exec->vm();
1453 vm.heap.writeBarrier(cell);
1456 extern "C" NO_RETURN_DUE_TO_CRASH void llint_crash()
1461 } } // namespace JSC::LLInt