2 * Copyright (C) 2011, 2012, 2013 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 "CommonSlowPathsExceptions.h"
36 #include "GetterSetter.h"
37 #include "HostCallReturnValue.h"
38 #include "Interpreter.h"
40 #include "JITDriver.h"
41 #include "JSActivation.h"
42 #include "JSCJSValue.h"
43 #include "JSGlobalObjectFunctions.h"
44 #include "JSNameScope.h"
45 #include "JSPropertyNameIterator.h"
47 #include "JSWithScope.h"
48 #include "LLIntCommon.h"
49 #include "LLIntExceptions.h"
50 #include "LowLevelInterpreter.h"
51 #include "ObjectConstructor.h"
52 #include "Operations.h"
53 #include "StructureRareDataInlines.h"
54 #include <wtf/StringPrintStream.h>
56 namespace JSC { namespace LLInt {
58 #define LLINT_BEGIN_NO_SET_PC() \
59 VM& vm = exec->vm(); \
60 NativeCallFrameTracer tracer(&vm, exec)
63 #define LLINT_SET_PC_FOR_STUBS() do { \
64 exec->codeBlock()->bytecodeOffset(pc); \
65 exec->setCurrentVPC(pc + 1); \
68 #define LLINT_SET_PC_FOR_STUBS() do { \
69 exec->setCurrentVPC(pc + 1); \
73 #define LLINT_BEGIN() \
74 LLINT_BEGIN_NO_SET_PC(); \
75 LLINT_SET_PC_FOR_STUBS()
77 #define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
78 #define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
80 #define LLINT_RETURN_TWO(first, second) do { \
81 return encodeResult(first, second); \
84 #define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
86 #define LLINT_THROW(exceptionToThrow) do { \
87 vm.throwException(exec, exceptionToThrow); \
88 pc = returnToThrow(exec, pc); \
92 #define LLINT_CHECK_EXCEPTION() do { \
93 if (UNLIKELY(vm.exception())) { \
94 pc = returnToThrow(exec, pc); \
99 #define LLINT_END() do { \
100 LLINT_CHECK_EXCEPTION(); \
104 #define LLINT_BRANCH(opcode, condition) do { \
105 bool __b_condition = (condition); \
106 LLINT_CHECK_EXCEPTION(); \
108 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
110 pc += OPCODE_LENGTH(opcode); \
114 #define LLINT_RETURN(value) do { \
115 JSValue __r_returnValue = (value); \
116 LLINT_CHECK_EXCEPTION(); \
117 LLINT_OP(1) = __r_returnValue; \
121 #if ENABLE(VALUE_PROFILER)
122 #define LLINT_RETURN_PROFILED(opcode, value) do { \
123 JSValue __rp_returnValue = (value); \
124 LLINT_CHECK_EXCEPTION(); \
125 LLINT_OP(1) = __rp_returnValue; \
126 LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \
130 #define LLINT_PROFILE_VALUE(opcode, value) do { \
131 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
132 JSValue::encode(value); \
135 #else // ENABLE(VALUE_PROFILER)
136 #define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
138 #define LLINT_PROFILE_VALUE(opcode, value) do { } while (false)
140 #endif // ENABLE(VALUE_PROFILER)
142 #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
144 #define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
145 ExecState* __ct_exec = (exec); \
146 Instruction* __ct_pc = (pc); \
147 vm.throwException(__ct_exec, exceptionToThrow); \
148 LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
151 #define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
152 ExecState* __cce_exec = (exec); \
153 Instruction* __cce_pc = (pc); \
154 if (UNLIKELY(vm.exception())) \
155 LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
158 #define LLINT_CALL_RETURN(exec, pc, callTarget) do { \
159 ExecState* __cr_exec = (exec); \
160 Instruction* __cr_pc = (pc); \
161 void* __cr_callTarget = (callTarget); \
162 LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc); \
163 LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget); \
166 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
169 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
172 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
173 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
176 pc[operand].u.operand);
180 extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
182 JSValue value = LLINT_OP_C(operand).jsValue();
188 EncodedJSValue asValue;
190 u.asValue = JSValue::encode(value);
192 "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
195 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
196 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
199 pc[operand].u.operand,
202 toCString(value).data());
206 LLINT_SLOW_PATH_DECL(trace_prologue)
208 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
212 static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
214 JSFunction* callee = jsCast<JSFunction*>(exec->callee());
215 FunctionExecutable* executable = callee->jsExecutable();
216 CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
217 dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
218 codeBlock, exec, comment, callee, executable,
219 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
220 exec->callerFrame());
223 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
225 traceFunctionPrologue(exec, "call prologue", CodeForCall);
229 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
231 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
235 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
237 traceFunctionPrologue(exec, "call arity check", CodeForCall);
241 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
243 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
247 LLINT_SLOW_PATH_DECL(trace)
249 dataLogF("%p / %p: executing bc#%zu, %s, scope %p\n",
252 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
253 opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
255 if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
256 dataLogF("Will be returning to %p\n", exec->returnPC().value());
257 dataLogF("The new cfr will be %p\n", exec->callerFrame());
262 LLINT_SLOW_PATH_DECL(special_trace)
264 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
267 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
268 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
269 exec->returnPC().value());
274 inline bool shouldJIT(ExecState* exec)
276 // You can modify this to turn off JITting without rebuilding the world.
277 return exec->vm().canUseJIT();
280 // Returns true if we should try to OSR.
281 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
283 codeBlock->updateAllValueProfilePredictions();
285 if (!codeBlock->checkIfJITThresholdReached()) {
286 if (Options::verboseOSR())
287 dataLogF(" JIT threshold should be lifted.\n");
291 CompilationResult result = codeBlock->jitCompile(exec);
293 case CompilationNotNeeded:
294 if (Options::verboseOSR())
295 dataLogF(" Code was already compiled.\n");
296 codeBlock->jitSoon();
298 case CompilationFailed:
299 if (Options::verboseOSR())
300 dataLogF(" JIT compilation failed.\n");
301 codeBlock->dontJITAnytimeSoon();
303 case CompilationSuccessful:
304 if (Options::verboseOSR())
305 dataLogF(" JIT compilation successful.\n");
306 codeBlock->jitSoon();
309 RELEASE_ASSERT_NOT_REACHED();
314 enum EntryKind { Prologue, ArityCheck };
315 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
317 if (Options::verboseOSR()) {
319 *codeBlock, ": Entered ", name, " with executeCounter = ",
320 codeBlock->llintExecuteCounter(), "\n");
323 if (!shouldJIT(exec)) {
324 codeBlock->dontJITAnytimeSoon();
325 LLINT_RETURN_TWO(0, exec);
327 if (!jitCompileAndSetHeuristics(codeBlock, exec))
328 LLINT_RETURN_TWO(0, exec);
330 if (kind == Prologue)
331 LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), exec);
332 ASSERT(kind == ArityCheck);
333 LLINT_RETURN_TWO(codeBlock->jitCodeWithArityCheck().executableAddress(), exec);
336 LLINT_SLOW_PATH_DECL(entry_osr)
338 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
341 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
343 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
346 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
348 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
351 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
353 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
356 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
358 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
361 LLINT_SLOW_PATH_DECL(loop_osr)
363 CodeBlock* codeBlock = exec->codeBlock();
365 if (Options::verboseOSR()) {
367 *codeBlock, ": Entered loop_osr with executeCounter = ",
368 codeBlock->llintExecuteCounter(), "\n");
371 if (!shouldJIT(exec)) {
372 codeBlock->dontJITAnytimeSoon();
373 LLINT_RETURN_TWO(0, exec);
376 if (!jitCompileAndSetHeuristics(codeBlock, exec))
377 LLINT_RETURN_TWO(0, exec);
379 ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
381 Vector<BytecodeAndMachineOffset> map;
382 codeBlock->jitCodeMap()->decode(map);
383 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
385 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
387 void* jumpTarget = codeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
390 LLINT_RETURN_TWO(jumpTarget, exec);
393 LLINT_SLOW_PATH_DECL(replace)
395 CodeBlock* codeBlock = exec->codeBlock();
397 if (Options::verboseOSR()) {
399 *codeBlock, ": Entered replace with executeCounter = ",
400 codeBlock->llintExecuteCounter(), "\n");
404 jitCompileAndSetHeuristics(codeBlock, exec);
406 codeBlock->dontJITAnytimeSoon();
409 #endif // ENABLE(JIT)
411 LLINT_SLOW_PATH_DECL(stack_check)
414 #if LLINT_SLOW_PATH_TRACING
415 dataLogF("Checking stack height with exec = %p.\n", exec);
416 dataLogF("CodeBlock = %p.\n", exec->codeBlock());
417 dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
418 dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
419 dataLogF("Current end is at %p.\n", exec->vm().interpreter->stack().end());
421 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->vm().interpreter->stack().end());
422 if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
423 ReturnAddressPtr returnPC = exec->returnPC();
424 exec = exec->callerFrame();
425 vm.throwException(exec, createStackOverflowError(exec));
426 CommonSlowPaths::interpreterThrowInCaller(exec, returnPC);
427 pc = returnToThrowForThrownException(exec);
432 LLINT_SLOW_PATH_DECL(slow_path_create_activation)
435 #if LLINT_SLOW_PATH_TRACING
436 dataLogF("Creating an activation, exec = %p!\n", exec);
438 JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
439 exec->setScope(activation);
440 LLINT_RETURN(JSValue(activation));
443 LLINT_SLOW_PATH_DECL(slow_path_new_object)
446 LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
449 LLINT_SLOW_PATH_DECL(slow_path_new_array)
452 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
455 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
458 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
461 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
464 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
467 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
470 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
471 if (!regExp->isValid())
472 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
473 LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
476 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
480 JSValue value = LLINT_OP_C(2).jsValue();
481 JSValue baseVal = LLINT_OP_C(3).jsValue();
482 if (baseVal.isObject()) {
483 JSObject* baseObject = asObject(baseVal);
484 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
485 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
486 pc += pc[4].u.operand;
487 LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
490 LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
493 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
496 JSValue value = LLINT_OP_C(2).jsValue();
497 JSValue proto = LLINT_OP_C(3).jsValue();
498 ASSERT(!value.isObject() || !proto.isObject());
499 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
502 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
505 CodeBlock* codeBlock = exec->codeBlock();
506 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
507 JSValue baseValue = LLINT_OP_C(2).jsValue();
508 PropertySlot slot(baseValue);
510 JSValue result = baseValue.get(exec, ident, slot);
511 LLINT_CHECK_EXCEPTION();
512 LLINT_OP(1) = result;
514 if (!LLINT_ALWAYS_ACCESS_SLOW
515 && baseValue.isCell()
516 && slot.isCacheable()
517 && slot.slotBase() == baseValue
518 && slot.isCacheableValue()) {
520 JSCell* baseCell = baseValue.asCell();
521 Structure* structure = baseCell->structure();
523 if (!structure->isUncacheableDictionary()
524 && !structure->typeInfo().prohibitsPropertyCaching()) {
525 ConcurrentJITLocker locker(codeBlock->m_lock);
527 pc[4].u.structure.set(
528 vm, codeBlock->ownerExecutable(), structure);
529 if (isInlineOffset(slot.cachedOffset())) {
530 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
531 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
533 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
534 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
539 if (!LLINT_ALWAYS_ACCESS_SLOW
540 && isJSArray(baseValue)
541 && ident == exec->propertyNames().length) {
542 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
543 #if ENABLE(VALUE_PROFILER)
544 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
545 arrayProfile->observeStructure(baseValue.asCell()->structure());
546 pc[4].u.arrayProfile = arrayProfile;
550 #if ENABLE(VALUE_PROFILER)
551 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
556 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
559 CodeBlock* codeBlock = exec->codeBlock();
560 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
561 JSValue baseValue = LLINT_OP(2).jsValue();
562 PropertySlot slot(baseValue);
563 LLINT_RETURN(baseValue.get(exec, ident, slot));
566 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
569 CodeBlock* codeBlock = exec->codeBlock();
570 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
572 JSValue baseValue = LLINT_OP_C(1).jsValue();
573 PutPropertySlot slot(codeBlock->isStrictMode(), codeBlock->putByIdContext());
575 asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
577 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
578 LLINT_CHECK_EXCEPTION();
580 if (!LLINT_ALWAYS_ACCESS_SLOW
581 && baseValue.isCell()
582 && slot.isCacheable()) {
584 JSCell* baseCell = baseValue.asCell();
585 Structure* structure = baseCell->structure();
587 if (!structure->isUncacheableDictionary()
588 && !structure->typeInfo().prohibitsPropertyCaching()
589 && baseCell == slot.base()) {
591 if (slot.type() == PutPropertySlot::NewProperty) {
592 ConcurrentJITLocker locker(codeBlock->m_lock);
594 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
595 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
597 // This is needed because some of the methods we call
599 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
601 if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
602 ASSERT(structure->previousID()->isObject());
603 pc[4].u.structure.set(
604 vm, codeBlock->ownerExecutable(), structure->previousID());
605 if (isInlineOffset(slot.cachedOffset()))
606 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
608 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
609 pc[6].u.structure.set(
610 vm, codeBlock->ownerExecutable(), structure);
611 StructureChain* chain = structure->prototypeChain(exec);
613 pc[7].u.structureChain.set(
614 vm, codeBlock->ownerExecutable(), chain);
616 if (pc[8].u.operand) {
617 if (isInlineOffset(slot.cachedOffset()))
618 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct);
620 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line);
622 if (isInlineOffset(slot.cachedOffset()))
623 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal);
625 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line);
630 pc[4].u.structure.set(
631 vm, codeBlock->ownerExecutable(), structure);
632 if (isInlineOffset(slot.cachedOffset())) {
633 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
634 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
636 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
637 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
646 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
649 CodeBlock* codeBlock = exec->codeBlock();
650 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
651 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
652 LLINT_CHECK_EXCEPTION();
653 if (!couldDelete && codeBlock->isStrictMode())
654 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
655 LLINT_RETURN(jsBoolean(couldDelete));
658 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
660 if (LIKELY(baseValue.isCell() && subscript.isString())) {
661 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
665 if (subscript.isUInt32()) {
666 uint32_t i = subscript.asUInt32();
667 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
668 return asString(baseValue)->getIndex(exec, i);
670 return baseValue.get(exec, i);
673 if (isName(subscript))
674 return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
676 Identifier property(exec, subscript.toString(exec)->value(exec));
677 return baseValue.get(exec, property);
680 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
683 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
686 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
689 JSValue arguments = LLINT_OP(2).jsValue();
691 arguments = Arguments::create(vm, exec);
692 LLINT_CHECK_EXCEPTION();
693 LLINT_OP(2) = arguments;
694 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
697 LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
700 LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
703 LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
706 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
710 JSValue baseValue = LLINT_OP_C(1).jsValue();
711 JSValue subscript = LLINT_OP_C(2).jsValue();
712 JSValue value = LLINT_OP_C(3).jsValue();
714 if (LIKELY(subscript.isUInt32())) {
715 uint32_t i = subscript.asUInt32();
716 if (baseValue.isObject()) {
717 JSObject* object = asObject(baseValue);
718 if (object->canSetIndexQuickly(i))
719 object->setIndexQuickly(vm, i, value);
721 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
724 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
728 if (isName(subscript)) {
729 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
730 baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
734 Identifier property(exec, subscript.toString(exec)->value(exec));
735 LLINT_CHECK_EXCEPTION();
736 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
737 baseValue.put(exec, property, value, slot);
741 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
744 JSValue baseValue = LLINT_OP_C(2).jsValue();
745 JSObject* baseObject = baseValue.toObject(exec);
747 JSValue subscript = LLINT_OP_C(3).jsValue();
752 if (subscript.getUInt32(i))
753 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
754 else if (isName(subscript))
755 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
757 LLINT_CHECK_EXCEPTION();
758 Identifier property(exec, subscript.toString(exec)->value(exec));
759 LLINT_CHECK_EXCEPTION();
760 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
763 if (!couldDelete && exec->codeBlock()->isStrictMode())
764 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
766 LLINT_RETURN(jsBoolean(couldDelete));
769 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
772 JSValue arrayValue = LLINT_OP_C(1).jsValue();
773 ASSERT(isJSArray(arrayValue));
774 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
778 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
781 ASSERT(LLINT_OP(1).jsValue().isObject());
782 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
784 GetterSetter* accessor = GetterSetter::create(exec);
785 LLINT_CHECK_EXCEPTION();
787 JSValue getter = LLINT_OP(3).jsValue();
788 JSValue setter = LLINT_OP(4).jsValue();
789 ASSERT(getter.isObject() || getter.isUndefined());
790 ASSERT(setter.isObject() || setter.isUndefined());
791 ASSERT(getter.isObject() || setter.isObject());
793 if (!getter.isUndefined())
794 accessor->setGetter(vm, asObject(getter));
795 if (!setter.isUndefined())
796 accessor->setSetter(vm, asObject(setter));
797 baseObj->putDirectAccessor(
799 exec->codeBlock()->identifier(pc[2].u.operand),
804 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
807 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
810 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
813 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
816 LLINT_SLOW_PATH_DECL(slow_path_jless)
819 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
822 LLINT_SLOW_PATH_DECL(slow_path_jnless)
825 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
828 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
831 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
834 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
837 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
840 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
843 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
846 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
849 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
852 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
855 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
858 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
861 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
864 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
867 JSValue scrutinee = LLINT_OP_C(3).jsValue();
868 ASSERT(scrutinee.isDouble());
869 double value = scrutinee.asDouble();
870 int32_t intValue = static_cast<int32_t>(value);
871 int defaultOffset = pc[2].u.operand;
872 if (value == intValue) {
873 CodeBlock* codeBlock = exec->codeBlock();
874 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
880 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
883 JSValue scrutinee = LLINT_OP_C(3).jsValue();
884 ASSERT(scrutinee.isString());
885 JSString* string = asString(scrutinee);
886 ASSERT(string->length() == 1);
887 int defaultOffset = pc[2].u.operand;
888 StringImpl* impl = string->value(exec).impl();
889 CodeBlock* codeBlock = exec->codeBlock();
890 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
894 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
897 JSValue scrutinee = LLINT_OP_C(3).jsValue();
898 int defaultOffset = pc[2].u.operand;
899 if (!scrutinee.isString())
902 CodeBlock* codeBlock = exec->codeBlock();
903 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
908 LLINT_SLOW_PATH_DECL(slow_path_new_func)
911 CodeBlock* codeBlock = exec->codeBlock();
912 ASSERT(codeBlock->codeType() != FunctionCode
913 || !codeBlock->needsFullScopeChain()
914 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
915 #if LLINT_SLOW_PATH_TRACING
916 dataLogF("Creating function!\n");
918 LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
921 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
924 CodeBlock* codeBlock = exec->codeBlock();
925 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
926 JSFunction* func = JSFunction::create(exec, function, exec->scope());
931 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
933 ExecState* exec = execCallee->callerFrame();
936 execCallee->setScope(exec->scope());
937 execCallee->setCodeBlock(0);
938 execCallee->clearReturnPC();
940 if (kind == CodeForCall) {
942 CallType callType = getCallData(callee, callData);
944 ASSERT(callType != CallTypeJS);
946 if (callType == CallTypeHost) {
947 NativeCallFrameTracer tracer(&vm, execCallee);
948 execCallee->setCallee(asObject(callee));
949 vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
951 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
954 #if LLINT_SLOW_PATH_TRACING
955 dataLog("Call callee is not a function: ", callee, "\n");
958 ASSERT(callType == CallTypeNone);
959 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
962 ASSERT(kind == CodeForConstruct);
964 ConstructData constructData;
965 ConstructType constructType = getConstructData(callee, constructData);
967 ASSERT(constructType != ConstructTypeJS);
969 if (constructType == ConstructTypeHost) {
970 NativeCallFrameTracer tracer(&vm, execCallee);
971 execCallee->setCallee(asObject(callee));
972 vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
974 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
977 #if LLINT_SLOW_PATH_TRACING
978 dataLog("Constructor callee is not a function: ", callee, "\n");
981 ASSERT(constructType == ConstructTypeNone);
982 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
985 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
987 #if LLINT_SLOW_PATH_TRACING
988 dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
991 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
992 if (!calleeAsFunctionCell)
993 return handleHostCall(execCallee, pc, calleeAsValue, kind);
995 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
996 JSScope* scope = callee->scopeUnchecked();
997 VM& vm = *scope->vm();
998 execCallee->setScope(scope);
999 ExecutableBase* executable = callee->executable();
1001 MacroAssemblerCodePtr codePtr;
1002 CodeBlock* codeBlock = 0;
1003 if (executable->isHostFunction())
1004 codePtr = executable->hostCodeEntryFor(kind);
1006 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1007 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1009 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1010 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1012 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1013 codePtr = functionExecutable->jsCodeWithArityCheckEntryFor(kind);
1015 codePtr = functionExecutable->jsCodeEntryFor(kind);
1018 if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1019 ExecState* execCaller = execCallee->callerFrame();
1021 CodeBlock* callerCodeBlock = execCaller->codeBlock();
1023 ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1025 if (callLinkInfo->isOnList())
1026 callLinkInfo->remove();
1027 callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1028 callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1029 callLinkInfo->machineCodeTarget = codePtr;
1031 codeBlock->linkIncomingCall(execCaller, callLinkInfo);
1034 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1037 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1040 // - Set up a call frame.
1041 // - Figure out what to call and compile it if necessary.
1042 // - If possible, link the call's inline cache.
1043 // - Return a tuple of machine code address to call and the new call frame.
1045 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1047 ExecState* execCallee = exec + pc[4].u.operand;
1049 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1050 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1051 execCallee->setCallerFrame(exec);
1053 ASSERT(pc[5].u.callLinkInfo);
1054 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1057 LLINT_SLOW_PATH_DECL(slow_path_call)
1059 LLINT_BEGIN_NO_SET_PC();
1060 return genericCall(exec, pc, CodeForCall);
1063 LLINT_SLOW_PATH_DECL(slow_path_construct)
1065 LLINT_BEGIN_NO_SET_PC();
1066 return genericCall(exec, pc, CodeForConstruct);
1069 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1073 // - Set up a call frame while respecting the variable arguments.
1074 // - Figure out what to call and compile it if necessary.
1075 // - Return a tuple of machine code address to call and the new call frame.
1077 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1079 ExecState* execCallee = loadVarargs(
1080 exec, &vm.interpreter->stack(),
1081 LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[5].u.operand);
1082 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1084 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1085 execCallee->setCallerFrame(exec);
1086 exec->setCurrentVPC(pc);
1088 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1091 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1093 LLINT_BEGIN_NO_SET_PC();
1094 JSValue calleeAsValue = LLINT_OP(2).jsValue();
1096 ExecState* execCallee = exec + pc[4].u.operand;
1098 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1099 execCallee->setCallerFrame(exec);
1100 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1101 execCallee->setScope(exec->scope());
1102 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1103 execCallee->setCodeBlock(0);
1104 exec->setCurrentVPC(pc);
1106 if (!isHostFunction(calleeAsValue, globalFuncEval))
1107 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1109 vm.hostCallReturnValue = eval(execCallee);
1110 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1113 LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1116 ASSERT(exec->codeBlock()->needsFullScopeChain());
1117 jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
1121 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1124 ASSERT(exec->codeBlock()->usesArguments());
1125 Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
1126 if (JSValue activationValue = LLINT_OP_C(2).jsValue())
1127 arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
1129 arguments->tearOff(exec);
1133 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1136 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1139 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1142 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1145 LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1148 JSValue v = LLINT_OP(2).jsValue();
1149 if (v.isUndefinedOrNull()) {
1150 pc += pc[5].u.operand;
1154 JSObject* o = v.toObject(exec);
1155 Structure* structure = o->structure();
1156 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1157 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1158 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1160 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1161 LLINT_OP(2) = JSValue(o);
1162 LLINT_OP(3) = Register::withInt(0);
1163 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1165 pc += OPCODE_LENGTH(op_get_pnames);
1169 LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1172 JSObject* base = asObject(LLINT_OP(2).jsValue());
1173 JSString* property = asString(LLINT_OP(1).jsValue());
1174 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1176 pc += pc[6].u.operand;
1177 } // Else, don't change the PC, so the interpreter will reloop.
1181 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1184 JSValue v = LLINT_OP_C(1).jsValue();
1185 JSObject* o = v.toObject(exec);
1186 LLINT_CHECK_EXCEPTION();
1188 exec->setScope(JSWithScope::create(exec, o));
1193 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1196 exec->setScope(exec->scope()->next());
1200 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1203 CodeBlock* codeBlock = exec->codeBlock();
1204 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
1205 exec->setScope(scope);
1209 LLINT_SLOW_PATH_DECL(slow_path_throw)
1212 LLINT_THROW(LLINT_OP_C(1).jsValue());
1215 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1218 if (pc[2].u.operand)
1219 LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1221 LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1224 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1226 LLINT_BEGIN_NO_SET_PC();
1227 if (UNLIKELY(vm.watchdog.didFire(exec)))
1228 LLINT_THROW(createTerminatedExecutionException(&vm));
1229 LLINT_RETURN_TWO(0, exec);
1232 LLINT_SLOW_PATH_DECL(slow_path_debug)
1235 int debugHookID = pc[1].u.operand;
1236 int firstLine = pc[2].u.operand;
1237 int lastLine = pc[3].u.operand;
1238 int column = pc[4].u.operand;
1240 vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
1245 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1248 if (LegacyProfiler* profiler = vm.enabledProfiler())
1249 profiler->willExecute(exec, LLINT_OP(1).jsValue());
1253 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1256 if (LegacyProfiler* profiler = vm.enabledProfiler())
1257 profiler->didExecute(exec, LLINT_OP(1).jsValue());
1261 LLINT_SLOW_PATH_DECL(throw_from_native_call)
1264 ASSERT(vm.exception());
1268 LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
1271 const Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
1272 LLINT_RETURN(JSScope::resolve(exec, exec->scope(), ident));
1275 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1278 const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1279 JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1280 ResolveModeAndType modeAndType(pc[4].u.operand);
1282 PropertySlot slot(scope);
1283 if (!scope->getPropertySlot(exec, ident, slot)) {
1284 if (modeAndType.mode() == ThrowIfNotFound)
1285 LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1286 LLINT_RETURN(jsUndefined());
1289 // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1290 if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1291 if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1292 CodeBlock* codeBlock = exec->codeBlock();
1293 ConcurrentJITLocker locker(codeBlock->m_lock);
1294 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
1295 pc[6].u.operand = slot.cachedOffset();
1299 LLINT_RETURN(slot.getValue(exec, ident));
1302 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1305 CodeBlock* codeBlock = exec->codeBlock();
1306 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1307 JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1308 JSValue value = LLINT_OP_C(3).jsValue();
1309 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1311 if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
1312 LLINT_THROW(createUndefinedVariableError(exec, ident));
1314 PutPropertySlot slot(codeBlock->isStrictMode());
1315 scope->methodTable()->put(scope, exec, ident, value, slot);
1317 // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1318 if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1319 if (slot.isCacheable() && slot.base() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1320 ConcurrentJITLocker locker(codeBlock->m_lock);
1321 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
1322 pc[6].u.operand = slot.cachedOffset();
1329 } } // namespace JSC::LLInt
1331 #endif // ENABLE(LLINT)