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 "JSActivation.h"
41 #include "JSCJSValue.h"
42 #include "JSGlobalObjectFunctions.h"
43 #include "JSNameScope.h"
44 #include "JSPropertyNameIterator.h"
46 #include "JSWithScope.h"
47 #include "LLIntCommon.h"
48 #include "LLIntExceptions.h"
49 #include "LowLevelInterpreter.h"
50 #include "ObjectConstructor.h"
51 #include "Operations.h"
52 #include "StructureRareDataInlines.h"
53 #include <wtf/StringPrintStream.h>
55 namespace JSC { namespace LLInt {
57 #define LLINT_BEGIN_NO_SET_PC() \
58 VM& vm = exec->vm(); \
59 NativeCallFrameTracer tracer(&vm, exec)
62 #define LLINT_SET_PC_FOR_STUBS() do { \
63 exec->codeBlock()->bytecodeOffset(pc); \
64 exec->setCurrentVPC(pc + 1); \
67 #define LLINT_SET_PC_FOR_STUBS() do { \
68 exec->setCurrentVPC(pc + 1); \
72 #define LLINT_BEGIN() \
73 LLINT_BEGIN_NO_SET_PC(); \
74 LLINT_SET_PC_FOR_STUBS()
76 #define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
77 #define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
79 #define LLINT_RETURN_TWO(first, second) do { \
80 return encodeResult(first, second); \
83 #define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
85 #define LLINT_THROW(exceptionToThrow) do { \
86 vm.throwException(exec, exceptionToThrow); \
87 pc = returnToThrow(exec, pc); \
91 #define LLINT_CHECK_EXCEPTION() do { \
92 if (UNLIKELY(vm.exception())) { \
93 pc = returnToThrow(exec, pc); \
98 #define LLINT_END() do { \
99 LLINT_CHECK_EXCEPTION(); \
103 #define LLINT_BRANCH(opcode, condition) do { \
104 bool __b_condition = (condition); \
105 LLINT_CHECK_EXCEPTION(); \
107 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
109 pc += OPCODE_LENGTH(opcode); \
113 #define LLINT_RETURN(value) do { \
114 JSValue __r_returnValue = (value); \
115 LLINT_CHECK_EXCEPTION(); \
116 LLINT_OP(1) = __r_returnValue; \
120 #if ENABLE(VALUE_PROFILER)
121 #define LLINT_RETURN_PROFILED(opcode, value) do { \
122 JSValue __rp_returnValue = (value); \
123 LLINT_CHECK_EXCEPTION(); \
124 LLINT_OP(1) = __rp_returnValue; \
125 LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \
129 #define LLINT_PROFILE_VALUE(opcode, value) do { \
130 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
131 JSValue::encode(value); \
134 #else // ENABLE(VALUE_PROFILER)
135 #define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
137 #define LLINT_PROFILE_VALUE(opcode, value) do { } while (false)
139 #endif // ENABLE(VALUE_PROFILER)
141 #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
143 #define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
144 ExecState* __ct_exec = (exec); \
145 Instruction* __ct_pc = (pc); \
146 vm.throwException(__ct_exec, exceptionToThrow); \
147 LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
150 #define LLINT_CALL_CHECK_EXCEPTION(exec, pc) do { \
151 ExecState* __cce_exec = (exec); \
152 Instruction* __cce_pc = (pc); \
153 if (UNLIKELY(vm.exception())) \
154 LLINT_CALL_END_IMPL(__cce_exec, callToThrow(__cce_exec, __cce_pc)); \
157 #define LLINT_CALL_RETURN(exec, pc, callTarget) do { \
158 ExecState* __cr_exec = (exec); \
159 Instruction* __cr_pc = (pc); \
160 void* __cr_callTarget = (callTarget); \
161 LLINT_CALL_CHECK_EXCEPTION(__cr_exec->callerFrame(), __cr_pc); \
162 LLINT_CALL_END_IMPL(__cr_exec, __cr_callTarget); \
165 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
168 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
171 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
172 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
175 pc[operand].u.operand);
179 extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
181 JSValue value = LLINT_OP_C(operand).jsValue();
187 EncodedJSValue asValue;
189 u.asValue = JSValue::encode(value);
191 "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
194 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
195 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
198 pc[operand].u.operand,
201 toCString(value).data());
205 LLINT_SLOW_PATH_DECL(trace_prologue)
207 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
211 static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
213 JSFunction* callee = jsCast<JSFunction*>(exec->callee());
214 FunctionExecutable* executable = callee->jsExecutable();
215 CodeBlock* codeBlock = &executable->generatedBytecodeFor(kind);
216 dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
217 codeBlock, exec, comment, callee, executable,
218 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
219 exec->callerFrame());
222 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
224 traceFunctionPrologue(exec, "call prologue", CodeForCall);
228 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
230 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
234 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
236 traceFunctionPrologue(exec, "call arity check", CodeForCall);
240 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
242 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
246 LLINT_SLOW_PATH_DECL(trace)
248 dataLogF("%p / %p: executing bc#%zu, %s, scope %p\n",
251 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
252 opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
254 if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
255 dataLogF("Will be returning to %p\n", exec->returnPC().value());
256 dataLogF("The new cfr will be %p\n", exec->callerFrame());
261 LLINT_SLOW_PATH_DECL(special_trace)
263 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
266 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
267 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
268 exec->returnPC().value());
273 inline bool shouldJIT(ExecState* exec)
275 // You can modify this to turn off JITting without rebuilding the world.
276 return exec->vm().canUseJIT();
279 // Returns true if we should try to OSR.
280 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
282 DeferGC deferGC(exec->vm().heap);
284 codeBlock->updateAllValueProfilePredictions();
286 if (!codeBlock->checkIfJITThresholdReached()) {
287 if (Options::verboseOSR())
288 dataLogF(" JIT threshold should be lifted.\n");
292 switch (codeBlock->jitType()) {
293 case JITCode::BaselineJIT: {
294 if (Options::verboseOSR())
295 dataLogF(" Code was already compiled.\n");
296 codeBlock->jitSoon();
299 case JITCode::InterpreterThunk: {
300 CompilationResult result = codeBlock->prepareForExecution(
301 exec, JITCode::BaselineJIT, JITCompilationCanFail);
303 case CompilationFailed:
304 if (Options::verboseOSR())
305 dataLogF(" JIT compilation failed.\n");
306 codeBlock->dontJITAnytimeSoon();
308 case CompilationSuccessful:
309 if (Options::verboseOSR())
310 dataLogF(" JIT compilation successful.\n");
311 codeBlock->install();
312 codeBlock->jitSoon();
315 RELEASE_ASSERT_NOT_REACHED();
320 RELEASE_ASSERT_NOT_REACHED();
325 enum EntryKind { Prologue, ArityCheck };
326 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
328 if (Options::verboseOSR()) {
330 *codeBlock, ": Entered ", name, " with executeCounter = ",
331 codeBlock->llintExecuteCounter(), "\n");
334 if (!shouldJIT(exec)) {
335 codeBlock->dontJITAnytimeSoon();
336 LLINT_RETURN_TWO(0, exec);
338 if (!jitCompileAndSetHeuristics(codeBlock, exec))
339 LLINT_RETURN_TWO(0, exec);
341 if (kind == Prologue)
342 LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), exec);
343 ASSERT(kind == ArityCheck);
344 LLINT_RETURN_TWO(codeBlock->jitCodeWithArityCheck().executableAddress(), exec);
347 LLINT_SLOW_PATH_DECL(entry_osr)
349 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
352 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
354 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
357 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
359 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
362 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
364 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
367 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
369 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
372 LLINT_SLOW_PATH_DECL(loop_osr)
374 CodeBlock* codeBlock = exec->codeBlock();
376 if (Options::verboseOSR()) {
378 *codeBlock, ": Entered loop_osr with executeCounter = ",
379 codeBlock->llintExecuteCounter(), "\n");
382 if (!shouldJIT(exec)) {
383 codeBlock->dontJITAnytimeSoon();
384 LLINT_RETURN_TWO(0, exec);
387 if (!jitCompileAndSetHeuristics(codeBlock, exec))
388 LLINT_RETURN_TWO(0, exec);
390 ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
392 Vector<BytecodeAndMachineOffset> map;
393 codeBlock->jitCodeMap()->decode(map);
394 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
396 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
398 void* jumpTarget = codeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
401 LLINT_RETURN_TWO(jumpTarget, exec);
404 LLINT_SLOW_PATH_DECL(replace)
406 CodeBlock* codeBlock = exec->codeBlock();
408 if (Options::verboseOSR()) {
410 *codeBlock, ": Entered replace with executeCounter = ",
411 codeBlock->llintExecuteCounter(), "\n");
415 jitCompileAndSetHeuristics(codeBlock, exec);
417 codeBlock->dontJITAnytimeSoon();
420 #endif // ENABLE(JIT)
422 LLINT_SLOW_PATH_DECL(stack_check)
425 #if LLINT_SLOW_PATH_TRACING
426 dataLogF("Checking stack height with exec = %p.\n", exec);
427 dataLogF("CodeBlock = %p.\n", exec->codeBlock());
428 dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
429 dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
430 dataLogF("Current end is at %p.\n", exec->vm().interpreter->stack().end());
432 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->vm().interpreter->stack().end());
433 if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
434 ReturnAddressPtr returnPC = exec->returnPC();
435 exec = exec->callerFrame();
436 vm.throwException(exec, createStackOverflowError(exec));
437 CommonSlowPaths::interpreterThrowInCaller(exec, returnPC);
438 pc = returnToThrowForThrownException(exec);
443 LLINT_SLOW_PATH_DECL(slow_path_create_activation)
446 #if LLINT_SLOW_PATH_TRACING
447 dataLogF("Creating an activation, exec = %p!\n", exec);
449 JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
450 exec->setScope(activation);
451 LLINT_RETURN(JSValue(activation));
454 LLINT_SLOW_PATH_DECL(slow_path_new_object)
457 LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
460 LLINT_SLOW_PATH_DECL(slow_path_new_array)
463 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
466 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
469 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
472 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
475 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
478 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
481 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
482 if (!regExp->isValid())
483 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
484 LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
487 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
491 JSValue value = LLINT_OP_C(2).jsValue();
492 JSValue baseVal = LLINT_OP_C(3).jsValue();
493 if (baseVal.isObject()) {
494 JSObject* baseObject = asObject(baseVal);
495 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
496 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
497 pc += pc[4].u.operand;
498 LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
501 LLINT_THROW(createInvalidParameterError(exec, "instanceof", baseVal));
504 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
507 JSValue value = LLINT_OP_C(2).jsValue();
508 JSValue proto = LLINT_OP_C(3).jsValue();
509 ASSERT(!value.isObject() || !proto.isObject());
510 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
513 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
516 CodeBlock* codeBlock = exec->codeBlock();
517 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
518 JSValue baseValue = LLINT_OP_C(2).jsValue();
519 PropertySlot slot(baseValue);
521 JSValue result = baseValue.get(exec, ident, slot);
522 LLINT_CHECK_EXCEPTION();
523 LLINT_OP(1) = result;
525 if (!LLINT_ALWAYS_ACCESS_SLOW
526 && baseValue.isCell()
527 && slot.isCacheable()
528 && slot.slotBase() == baseValue
529 && slot.isCacheableValue()) {
531 JSCell* baseCell = baseValue.asCell();
532 Structure* structure = baseCell->structure();
534 if (!structure->isUncacheableDictionary()
535 && !structure->typeInfo().prohibitsPropertyCaching()) {
536 ConcurrentJITLocker locker(codeBlock->m_lock);
538 pc[4].u.structure.set(
539 vm, codeBlock->ownerExecutable(), structure);
540 if (isInlineOffset(slot.cachedOffset())) {
541 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
542 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
544 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
545 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
550 if (!LLINT_ALWAYS_ACCESS_SLOW
551 && isJSArray(baseValue)
552 && ident == exec->propertyNames().length) {
553 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
554 #if ENABLE(VALUE_PROFILER)
555 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
556 arrayProfile->observeStructure(baseValue.asCell()->structure());
557 pc[4].u.arrayProfile = arrayProfile;
561 #if ENABLE(VALUE_PROFILER)
562 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
567 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
570 CodeBlock* codeBlock = exec->codeBlock();
571 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
572 JSValue baseValue = LLINT_OP(2).jsValue();
573 PropertySlot slot(baseValue);
574 LLINT_RETURN(baseValue.get(exec, ident, slot));
577 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
580 CodeBlock* codeBlock = exec->codeBlock();
581 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
583 JSValue baseValue = LLINT_OP_C(1).jsValue();
584 PutPropertySlot slot(codeBlock->isStrictMode(), codeBlock->putByIdContext());
586 asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
588 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
589 LLINT_CHECK_EXCEPTION();
591 if (!LLINT_ALWAYS_ACCESS_SLOW
592 && baseValue.isCell()
593 && slot.isCacheable()) {
595 JSCell* baseCell = baseValue.asCell();
596 Structure* structure = baseCell->structure();
598 if (!structure->isUncacheableDictionary()
599 && !structure->typeInfo().prohibitsPropertyCaching()
600 && baseCell == slot.base()) {
602 if (slot.type() == PutPropertySlot::NewProperty) {
603 ConcurrentJITLocker locker(codeBlock->m_lock);
605 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
606 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
608 // This is needed because some of the methods we call
610 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
612 if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
613 ASSERT(structure->previousID()->isObject());
614 pc[4].u.structure.set(
615 vm, codeBlock->ownerExecutable(), structure->previousID());
616 if (isInlineOffset(slot.cachedOffset()))
617 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
619 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
620 pc[6].u.structure.set(
621 vm, codeBlock->ownerExecutable(), structure);
622 StructureChain* chain = structure->prototypeChain(exec);
624 pc[7].u.structureChain.set(
625 vm, codeBlock->ownerExecutable(), chain);
627 if (pc[8].u.operand) {
628 if (isInlineOffset(slot.cachedOffset()))
629 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct);
631 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line);
633 if (isInlineOffset(slot.cachedOffset()))
634 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal);
636 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line);
641 pc[4].u.structure.set(
642 vm, codeBlock->ownerExecutable(), structure);
643 if (isInlineOffset(slot.cachedOffset())) {
644 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
645 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
647 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
648 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
657 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
660 CodeBlock* codeBlock = exec->codeBlock();
661 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
662 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
663 LLINT_CHECK_EXCEPTION();
664 if (!couldDelete && codeBlock->isStrictMode())
665 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
666 LLINT_RETURN(jsBoolean(couldDelete));
669 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
671 if (LIKELY(baseValue.isCell() && subscript.isString())) {
672 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
676 if (subscript.isUInt32()) {
677 uint32_t i = subscript.asUInt32();
678 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
679 return asString(baseValue)->getIndex(exec, i);
681 return baseValue.get(exec, i);
684 if (isName(subscript))
685 return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
687 Identifier property(exec, subscript.toString(exec)->value(exec));
688 return baseValue.get(exec, property);
691 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
694 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
697 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
700 JSValue arguments = LLINT_OP(2).jsValue();
702 arguments = Arguments::create(vm, exec);
703 LLINT_CHECK_EXCEPTION();
704 LLINT_OP(2) = arguments;
705 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
708 LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
711 LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
714 LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
717 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
721 JSValue baseValue = LLINT_OP_C(1).jsValue();
722 JSValue subscript = LLINT_OP_C(2).jsValue();
723 JSValue value = LLINT_OP_C(3).jsValue();
725 if (LIKELY(subscript.isUInt32())) {
726 uint32_t i = subscript.asUInt32();
727 if (baseValue.isObject()) {
728 JSObject* object = asObject(baseValue);
729 if (object->canSetIndexQuickly(i))
730 object->setIndexQuickly(vm, i, value);
732 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
735 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
739 if (isName(subscript)) {
740 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
741 baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
745 Identifier property(exec, subscript.toString(exec)->value(exec));
746 LLINT_CHECK_EXCEPTION();
747 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
748 baseValue.put(exec, property, value, slot);
752 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
755 JSValue baseValue = LLINT_OP_C(2).jsValue();
756 JSObject* baseObject = baseValue.toObject(exec);
758 JSValue subscript = LLINT_OP_C(3).jsValue();
763 if (subscript.getUInt32(i))
764 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
765 else if (isName(subscript))
766 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
768 LLINT_CHECK_EXCEPTION();
769 Identifier property(exec, subscript.toString(exec)->value(exec));
770 LLINT_CHECK_EXCEPTION();
771 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
774 if (!couldDelete && exec->codeBlock()->isStrictMode())
775 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
777 LLINT_RETURN(jsBoolean(couldDelete));
780 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
783 JSValue arrayValue = LLINT_OP_C(1).jsValue();
784 ASSERT(isJSArray(arrayValue));
785 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
789 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
792 ASSERT(LLINT_OP(1).jsValue().isObject());
793 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
795 GetterSetter* accessor = GetterSetter::create(exec);
796 LLINT_CHECK_EXCEPTION();
798 JSValue getter = LLINT_OP(3).jsValue();
799 JSValue setter = LLINT_OP(4).jsValue();
800 ASSERT(getter.isObject() || getter.isUndefined());
801 ASSERT(setter.isObject() || setter.isUndefined());
802 ASSERT(getter.isObject() || setter.isObject());
804 if (!getter.isUndefined())
805 accessor->setGetter(vm, asObject(getter));
806 if (!setter.isUndefined())
807 accessor->setSetter(vm, asObject(setter));
808 baseObj->putDirectAccessor(
810 exec->codeBlock()->identifier(pc[2].u.operand),
815 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
818 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
821 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
824 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
827 LLINT_SLOW_PATH_DECL(slow_path_jless)
830 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
833 LLINT_SLOW_PATH_DECL(slow_path_jnless)
836 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
839 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
842 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
845 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
848 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
851 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
854 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
857 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
860 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
863 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
866 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
869 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
872 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
875 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
878 JSValue scrutinee = LLINT_OP_C(3).jsValue();
879 ASSERT(scrutinee.isDouble());
880 double value = scrutinee.asDouble();
881 int32_t intValue = static_cast<int32_t>(value);
882 int defaultOffset = pc[2].u.operand;
883 if (value == intValue) {
884 CodeBlock* codeBlock = exec->codeBlock();
885 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
891 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
894 JSValue scrutinee = LLINT_OP_C(3).jsValue();
895 ASSERT(scrutinee.isString());
896 JSString* string = asString(scrutinee);
897 ASSERT(string->length() == 1);
898 int defaultOffset = pc[2].u.operand;
899 StringImpl* impl = string->value(exec).impl();
900 CodeBlock* codeBlock = exec->codeBlock();
901 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
905 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
908 JSValue scrutinee = LLINT_OP_C(3).jsValue();
909 int defaultOffset = pc[2].u.operand;
910 if (!scrutinee.isString())
913 CodeBlock* codeBlock = exec->codeBlock();
914 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
919 LLINT_SLOW_PATH_DECL(slow_path_new_func)
922 CodeBlock* codeBlock = exec->codeBlock();
923 ASSERT(codeBlock->codeType() != FunctionCode
924 || !codeBlock->needsFullScopeChain()
925 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
926 #if LLINT_SLOW_PATH_TRACING
927 dataLogF("Creating function!\n");
929 LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
932 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
935 CodeBlock* codeBlock = exec->codeBlock();
936 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
937 JSFunction* func = JSFunction::create(exec, function, exec->scope());
942 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
944 ExecState* exec = execCallee->callerFrame();
947 execCallee->setScope(exec->scope());
948 execCallee->setCodeBlock(0);
949 execCallee->clearReturnPC();
951 if (kind == CodeForCall) {
953 CallType callType = getCallData(callee, callData);
955 ASSERT(callType != CallTypeJS);
957 if (callType == CallTypeHost) {
958 NativeCallFrameTracer tracer(&vm, execCallee);
959 execCallee->setCallee(asObject(callee));
960 vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
962 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
965 #if LLINT_SLOW_PATH_TRACING
966 dataLog("Call callee is not a function: ", callee, "\n");
969 ASSERT(callType == CallTypeNone);
970 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
973 ASSERT(kind == CodeForConstruct);
975 ConstructData constructData;
976 ConstructType constructType = getConstructData(callee, constructData);
978 ASSERT(constructType != ConstructTypeJS);
980 if (constructType == ConstructTypeHost) {
981 NativeCallFrameTracer tracer(&vm, execCallee);
982 execCallee->setCallee(asObject(callee));
983 vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
985 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
988 #if LLINT_SLOW_PATH_TRACING
989 dataLog("Constructor callee is not a function: ", callee, "\n");
992 ASSERT(constructType == ConstructTypeNone);
993 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
996 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
998 #if LLINT_SLOW_PATH_TRACING
999 dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
1002 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1003 if (!calleeAsFunctionCell)
1004 return handleHostCall(execCallee, pc, calleeAsValue, kind);
1006 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1007 JSScope* scope = callee->scopeUnchecked();
1008 VM& vm = *scope->vm();
1009 execCallee->setScope(scope);
1010 ExecutableBase* executable = callee->executable();
1012 MacroAssemblerCodePtr codePtr;
1013 CodeBlock* codeBlock = 0;
1014 if (executable->isHostFunction())
1015 codePtr = executable->hostCodeEntryFor(kind);
1017 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1018 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
1020 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1021 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1023 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1024 codePtr = functionExecutable->jsCodeWithArityCheckEntryFor(kind);
1026 codePtr = functionExecutable->jsCodeEntryFor(kind);
1029 if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1030 ExecState* execCaller = execCallee->callerFrame();
1032 CodeBlock* callerCodeBlock = execCaller->codeBlock();
1034 ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1036 if (callLinkInfo->isOnList())
1037 callLinkInfo->remove();
1038 callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1039 callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1040 callLinkInfo->machineCodeTarget = codePtr;
1042 codeBlock->linkIncomingCall(execCaller, callLinkInfo);
1045 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1048 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1051 // - Set up a call frame.
1052 // - Figure out what to call and compile it if necessary.
1053 // - If possible, link the call's inline cache.
1054 // - Return a tuple of machine code address to call and the new call frame.
1056 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1058 ExecState* execCallee = exec + pc[4].u.operand;
1060 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1061 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1062 execCallee->setCallerFrame(exec);
1064 ASSERT(pc[5].u.callLinkInfo);
1065 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
1068 LLINT_SLOW_PATH_DECL(slow_path_call)
1070 LLINT_BEGIN_NO_SET_PC();
1071 return genericCall(exec, pc, CodeForCall);
1074 LLINT_SLOW_PATH_DECL(slow_path_construct)
1076 LLINT_BEGIN_NO_SET_PC();
1077 return genericCall(exec, pc, CodeForConstruct);
1080 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1084 // - Set up a call frame while respecting the variable arguments.
1085 // - Figure out what to call and compile it if necessary.
1086 // - Return a tuple of machine code address to call and the new call frame.
1088 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1090 ExecState* execCallee = loadVarargs(
1091 exec, &vm.interpreter->stack(),
1092 LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[5].u.operand);
1093 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1095 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1096 execCallee->setCallerFrame(exec);
1097 exec->setCurrentVPC(pc);
1099 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1102 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1104 LLINT_BEGIN_NO_SET_PC();
1105 JSValue calleeAsValue = LLINT_OP(2).jsValue();
1107 ExecState* execCallee = exec + pc[4].u.operand;
1109 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
1110 execCallee->setCallerFrame(exec);
1111 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1112 execCallee->setScope(exec->scope());
1113 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1114 execCallee->setCodeBlock(0);
1115 exec->setCurrentVPC(pc);
1117 if (!isHostFunction(calleeAsValue, globalFuncEval))
1118 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1120 vm.hostCallReturnValue = eval(execCallee);
1121 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1124 LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1127 ASSERT(exec->codeBlock()->needsFullScopeChain());
1128 jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
1132 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1135 ASSERT(exec->codeBlock()->usesArguments());
1136 Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
1137 if (JSValue activationValue = LLINT_OP_C(2).jsValue())
1138 arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
1140 arguments->tearOff(exec);
1144 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1147 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1150 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1153 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1156 LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1159 JSValue v = LLINT_OP(2).jsValue();
1160 if (v.isUndefinedOrNull()) {
1161 pc += pc[5].u.operand;
1165 JSObject* o = v.toObject(exec);
1166 Structure* structure = o->structure();
1167 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1168 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1169 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1171 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1172 LLINT_OP(2) = JSValue(o);
1173 LLINT_OP(3) = Register::withInt(0);
1174 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1176 pc += OPCODE_LENGTH(op_get_pnames);
1180 LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1183 JSObject* base = asObject(LLINT_OP(2).jsValue());
1184 JSString* property = asString(LLINT_OP(1).jsValue());
1185 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1187 pc += pc[6].u.operand;
1188 } // Else, don't change the PC, so the interpreter will reloop.
1192 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1195 JSValue v = LLINT_OP_C(1).jsValue();
1196 JSObject* o = v.toObject(exec);
1197 LLINT_CHECK_EXCEPTION();
1199 exec->setScope(JSWithScope::create(exec, o));
1204 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1207 exec->setScope(exec->scope()->next());
1211 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1214 CodeBlock* codeBlock = exec->codeBlock();
1215 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
1216 exec->setScope(scope);
1220 LLINT_SLOW_PATH_DECL(slow_path_throw)
1223 LLINT_THROW(LLINT_OP_C(1).jsValue());
1226 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1229 if (pc[2].u.operand)
1230 LLINT_THROW(createReferenceError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1232 LLINT_THROW(createTypeError(exec, errorDescriptionForValue(exec, LLINT_OP_C(1).jsValue())->value(exec)));
1235 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1237 LLINT_BEGIN_NO_SET_PC();
1238 if (UNLIKELY(vm.watchdog.didFire(exec)))
1239 LLINT_THROW(createTerminatedExecutionException(&vm));
1240 LLINT_RETURN_TWO(0, exec);
1243 LLINT_SLOW_PATH_DECL(slow_path_debug)
1246 int debugHookID = pc[1].u.operand;
1247 int firstLine = pc[2].u.operand;
1248 int lastLine = pc[3].u.operand;
1249 int column = pc[4].u.operand;
1251 vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
1256 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1259 if (LegacyProfiler* profiler = vm.enabledProfiler())
1260 profiler->willExecute(exec, LLINT_OP(1).jsValue());
1264 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1267 if (LegacyProfiler* profiler = vm.enabledProfiler())
1268 profiler->didExecute(exec, LLINT_OP(1).jsValue());
1272 LLINT_SLOW_PATH_DECL(throw_from_native_call)
1275 ASSERT(vm.exception());
1279 LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
1282 const Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
1283 LLINT_RETURN(JSScope::resolve(exec, exec->scope(), ident));
1286 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1289 const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1290 JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1291 ResolveModeAndType modeAndType(pc[4].u.operand);
1293 PropertySlot slot(scope);
1294 if (!scope->getPropertySlot(exec, ident, slot)) {
1295 if (modeAndType.mode() == ThrowIfNotFound)
1296 LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1297 LLINT_RETURN(jsUndefined());
1300 // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1301 if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1302 if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1303 CodeBlock* codeBlock = exec->codeBlock();
1304 ConcurrentJITLocker locker(codeBlock->m_lock);
1305 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
1306 pc[6].u.operand = slot.cachedOffset();
1310 LLINT_RETURN(slot.getValue(exec, ident));
1313 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
1316 CodeBlock* codeBlock = exec->codeBlock();
1317 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1318 JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1319 JSValue value = LLINT_OP_C(3).jsValue();
1320 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1322 if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
1323 LLINT_THROW(createUndefinedVariableError(exec, ident));
1325 PutPropertySlot slot(codeBlock->isStrictMode());
1326 scope->methodTable()->put(scope, exec, ident, value, slot);
1328 // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1329 if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1330 if (slot.isCacheable() && slot.base() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1331 ConcurrentJITLocker locker(codeBlock->m_lock);
1332 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
1333 pc[6].u.operand = slot.cachedOffset();
1340 } } // namespace JSC::LLInt
1342 #endif // ENABLE(LLINT)