]> git.saurik.com Git - apple/javascriptcore.git/blame - llint/LLIntSlowPaths.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / llint / LLIntSlowPaths.cpp
CommitLineData
6fe7ccc8 1/*
ed1e77d3 2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
6fe7ccc8
A
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "LLIntSlowPaths.h"
ed1e77d3 28
93a37866 29#include "ArrayConstructor.h"
6fe7ccc8
A
30#include "CallFrame.h"
31#include "CommonSlowPaths.h"
81345200 32#include "CommonSlowPathsExceptions.h"
ed1e77d3 33#include "Error.h"
81345200 34#include "ErrorHandlingScope.h"
ed1e77d3 35#include "ExceptionFuzz.h"
6fe7ccc8
A
36#include "GetterSetter.h"
37#include "HostCallReturnValue.h"
38#include "Interpreter.h"
39#include "JIT.h"
81345200 40#include "JITExceptions.h"
ed1e77d3
A
41#include "JSLexicalEnvironment.h"
42#include "JSCInlines.h"
93a37866 43#include "JSCJSValue.h"
6fe7ccc8 44#include "JSGlobalObjectFunctions.h"
93a37866 45#include "JSNameScope.h"
81345200 46#include "JSStackInlines.h"
6fe7ccc8 47#include "JSString.h"
93a37866 48#include "JSWithScope.h"
6fe7ccc8
A
49#include "LLIntCommon.h"
50#include "LLIntExceptions.h"
ed1e77d3 51#include "LegacyProfiler.h"
6fe7ccc8 52#include "LowLevelInterpreter.h"
93a37866 53#include "ObjectConstructor.h"
81345200 54#include "ProtoCallFrame.h"
93a37866
A
55#include "StructureRareDataInlines.h"
56#include <wtf/StringPrintStream.h>
6fe7ccc8
A
57
58namespace JSC { namespace LLInt {
59
60#define LLINT_BEGIN_NO_SET_PC() \
93a37866
A
61 VM& vm = exec->vm(); \
62 NativeCallFrameTracer tracer(&vm, exec)
6fe7ccc8
A
63
64#ifndef NDEBUG
65#define LLINT_SET_PC_FOR_STUBS() do { \
66 exec->codeBlock()->bytecodeOffset(pc); \
67 exec->setCurrentVPC(pc + 1); \
68 } while (false)
69#else
70#define LLINT_SET_PC_FOR_STUBS() do { \
71 exec->setCurrentVPC(pc + 1); \
72 } while (false)
73#endif
74
75#define LLINT_BEGIN() \
76 LLINT_BEGIN_NO_SET_PC(); \
77 LLINT_SET_PC_FOR_STUBS()
78
79#define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
80#define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
81
82#define LLINT_RETURN_TWO(first, second) do { \
83 return encodeResult(first, second); \
84 } while (false)
85
81345200 86#define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, 0)
6fe7ccc8
A
87
88#define LLINT_THROW(exceptionToThrow) do { \
81345200
A
89 vm.throwException(exec, exceptionToThrow); \
90 pc = returnToThrow(exec); \
6fe7ccc8
A
91 LLINT_END_IMPL(); \
92 } while (false)
93
94#define LLINT_CHECK_EXCEPTION() do { \
ed1e77d3 95 doExceptionFuzzingIfEnabled(exec, "LLIntSlowPaths", pc); \
81345200
A
96 if (UNLIKELY(vm.exception())) { \
97 pc = returnToThrow(exec); \
6fe7ccc8
A
98 LLINT_END_IMPL(); \
99 } \
100 } while (false)
101
102#define LLINT_END() do { \
103 LLINT_CHECK_EXCEPTION(); \
104 LLINT_END_IMPL(); \
105 } while (false)
106
107#define LLINT_BRANCH(opcode, condition) do { \
108 bool __b_condition = (condition); \
109 LLINT_CHECK_EXCEPTION(); \
110 if (__b_condition) \
111 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
112 else \
113 pc += OPCODE_LENGTH(opcode); \
114 LLINT_END_IMPL(); \
115 } while (false)
116
117#define LLINT_RETURN(value) do { \
118 JSValue __r_returnValue = (value); \
119 LLINT_CHECK_EXCEPTION(); \
120 LLINT_OP(1) = __r_returnValue; \
121 LLINT_END_IMPL(); \
122 } while (false)
123
4be4e309
A
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); \
129 LLINT_END_IMPL(); \
130 } while (false)
131
6fe7ccc8
A
132#define LLINT_RETURN_PROFILED(opcode, value) do { \
133 JSValue __rp_returnValue = (value); \
134 LLINT_CHECK_EXCEPTION(); \
135 LLINT_OP(1) = __rp_returnValue; \
93a37866 136 LLINT_PROFILE_VALUE(opcode, __rp_returnValue); \
6fe7ccc8
A
137 LLINT_END_IMPL(); \
138 } while (false)
93a37866
A
139
140#define LLINT_PROFILE_VALUE(opcode, value) do { \
141 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
142 JSValue::encode(value); \
143 } while (false)
144
6fe7ccc8
A
145#define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
146
81345200 147#define LLINT_CALL_THROW(exec, exceptionToThrow) do { \
6fe7ccc8 148 ExecState* __ct_exec = (exec); \
81345200
A
149 vm.throwException(__ct_exec, exceptionToThrow); \
150 LLINT_CALL_END_IMPL(0, callToThrow(__ct_exec)); \
6fe7ccc8
A
151 } while (false)
152
ed1e77d3 153#define LLINT_CALL_CHECK_EXCEPTION(exec, execCallee) do { \
6fe7ccc8 154 ExecState* __cce_exec = (exec); \
ed1e77d3
A
155 ExecState* __cce_execCallee = (execCallee); \
156 doExceptionFuzzingIfEnabled(__cce_exec, "LLIntSlowPaths/call", nullptr); \
81345200 157 if (UNLIKELY(vm.exception())) \
ed1e77d3 158 LLINT_CALL_END_IMPL(0, callToThrow(__cce_execCallee)); \
6fe7ccc8
A
159 } while (false)
160
ed1e77d3 161#define LLINT_CALL_RETURN(exec, execCallee, callTarget) do { \
6fe7ccc8 162 ExecState* __cr_exec = (exec); \
ed1e77d3 163 ExecState* __cr_execCallee = (execCallee); \
6fe7ccc8 164 void* __cr_callTarget = (callTarget); \
ed1e77d3
A
165 LLINT_CALL_CHECK_EXCEPTION(__cr_exec, __cr_execCallee); \
166 LLINT_CALL_END_IMPL(__cr_execCallee, __cr_callTarget); \
6fe7ccc8
A
167 } while (false)
168
81345200
A
169#define LLINT_RETURN_CALLEE_FRAME(execCallee) do { \
170 ExecState* __rcf_exec = (execCallee); \
171 LLINT_RETURN_TWO(pc, __rcf_exec); \
172 } while (false)
81345200 173
6fe7ccc8
A
174extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
175{
176 LLINT_BEGIN();
93a37866 177 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
6fe7ccc8
A
178 exec->codeBlock(),
179 exec,
180 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
93a37866 181 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
6fe7ccc8
A
182 fromWhere,
183 operand,
184 pc[operand].u.operand);
185 LLINT_END();
186}
187
188extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
189{
190 JSValue value = LLINT_OP_C(operand).jsValue();
191 union {
192 struct {
193 uint32_t tag;
194 uint32_t payload;
195 } bits;
196 EncodedJSValue asValue;
197 } u;
198 u.asValue = JSValue::encode(value);
93a37866
A
199 dataLogF(
200 "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
201 exec->codeBlock(),
202 exec,
203 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
204 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
205 fromWhere,
206 operand,
207 pc[operand].u.operand,
208 u.bits.tag,
209 u.bits.payload,
210 toCString(value).data());
6fe7ccc8
A
211 LLINT_END_IMPL();
212}
213
214LLINT_SLOW_PATH_DECL(trace_prologue)
215{
93a37866 216 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
6fe7ccc8
A
217 LLINT_END_IMPL();
218}
219
220static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
221{
222 JSFunction* callee = jsCast<JSFunction*>(exec->callee());
223 FunctionExecutable* executable = callee->jsExecutable();
81345200 224 CodeBlock* codeBlock = executable->codeBlockFor(kind);
93a37866 225 dataLogF("%p / %p: in %s of function %p, executable %p; numVars = %u, numParameters = %u, numCalleeRegisters = %u, caller = %p.\n",
6fe7ccc8
A
226 codeBlock, exec, comment, callee, executable,
227 codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeRegisters,
228 exec->callerFrame());
229}
230
231LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
232{
233 traceFunctionPrologue(exec, "call prologue", CodeForCall);
234 LLINT_END_IMPL();
235}
236
237LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
238{
239 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
240 LLINT_END_IMPL();
241}
242
243LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
244{
245 traceFunctionPrologue(exec, "call arity check", CodeForCall);
246 LLINT_END_IMPL();
247}
248
249LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
250{
251 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
252 LLINT_END_IMPL();
253}
254
255LLINT_SLOW_PATH_DECL(trace)
256{
ed1e77d3 257 dataLogF("%p / %p: executing bc#%zu, %s, pc = %p\n",
6fe7ccc8
A
258 exec->codeBlock(),
259 exec,
260 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
ed1e77d3 261 opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)], pc);
81345200
A
262 if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_enter) {
263 dataLogF("Frame will eventually return to %p\n", exec->returnPC().value());
264 *bitwise_cast<volatile char*>(exec->returnPC().value());
265 }
93a37866
A
266 if (exec->vm().interpreter->getOpcodeID(pc[0].u.opcode) == op_ret) {
267 dataLogF("Will be returning to %p\n", exec->returnPC().value());
268 dataLogF("The new cfr will be %p\n", exec->callerFrame());
6fe7ccc8
A
269 }
270 LLINT_END_IMPL();
271}
272
273LLINT_SLOW_PATH_DECL(special_trace)
274{
93a37866 275 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
6fe7ccc8
A
276 exec->codeBlock(),
277 exec,
278 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
93a37866 279 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
6fe7ccc8
A
280 exec->returnPC().value());
281 LLINT_END_IMPL();
282}
283
81345200
A
284enum EntryKind { Prologue, ArityCheck };
285
93a37866 286#if ENABLE(JIT)
6fe7ccc8
A
287inline bool shouldJIT(ExecState* exec)
288{
289 // You can modify this to turn off JITting without rebuilding the world.
93a37866 290 return exec->vm().canUseJIT();
6fe7ccc8
A
291}
292
293// Returns true if we should try to OSR.
294inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
295{
81345200
A
296 VM& vm = exec->vm();
297 DeferGCForAWhile deferGC(vm.heap); // My callers don't set top callframe, so we don't want to GC here at all.
298
93a37866
A
299 codeBlock->updateAllValueProfilePredictions();
300
6fe7ccc8 301 if (!codeBlock->checkIfJITThresholdReached()) {
81345200
A
302 if (Options::verboseOSR())
303 dataLogF(" JIT threshold should be lifted.\n");
6fe7ccc8
A
304 return false;
305 }
81345200
A
306
307 switch (codeBlock->jitType()) {
308 case JITCode::BaselineJIT: {
309 if (Options::verboseOSR())
310 dataLogF(" Code was already compiled.\n");
6fe7ccc8
A
311 codeBlock->jitSoon();
312 return true;
81345200
A
313 }
314 case JITCode::InterpreterThunk: {
315 CompilationResult result = JIT::compile(&vm, codeBlock, JITCompilationCanFail);
316 switch (result) {
317 case CompilationFailed:
318 if (Options::verboseOSR())
319 dataLogF(" JIT compilation failed.\n");
320 codeBlock->dontJITAnytimeSoon();
321 return false;
322 case CompilationSuccessful:
323 if (Options::verboseOSR())
324 dataLogF(" JIT compilation successful.\n");
325 codeBlock->install();
326 codeBlock->jitSoon();
327 return true;
328 default:
329 RELEASE_ASSERT_NOT_REACHED();
330 return false;
331 }
332 }
333 default:
ed1e77d3 334 dataLog("Unexpected code block in LLInt: ", *codeBlock, "\n");
81345200 335 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8 336 return false;
6fe7ccc8 337 }
6fe7ccc8
A
338}
339
93a37866 340static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
6fe7ccc8 341{
81345200
A
342 if (Options::verboseOSR()) {
343 dataLog(
344 *codeBlock, ": Entered ", name, " with executeCounter = ",
345 codeBlock->llintExecuteCounter(), "\n");
346 }
6fe7ccc8
A
347
348 if (!shouldJIT(exec)) {
349 codeBlock->dontJITAnytimeSoon();
81345200 350 LLINT_RETURN_TWO(0, 0);
6fe7ccc8
A
351 }
352 if (!jitCompileAndSetHeuristics(codeBlock, exec))
81345200 353 LLINT_RETURN_TWO(0, 0);
6fe7ccc8
A
354
355 if (kind == Prologue)
81345200 356 LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), 0);
6fe7ccc8 357 ASSERT(kind == ArityCheck);
81345200
A
358 LLINT_RETURN_TWO(codeBlock->jitCode()->addressForCall(
359 *codeBlock->vm(), codeBlock->ownerExecutable(), MustCheckArity,
360 RegisterPreservationNotRequired).executableAddress(), 0);
361}
362#else // ENABLE(JIT)
363static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char*, EntryKind)
364{
365 codeBlock->dontJITAnytimeSoon();
366 LLINT_RETURN_TWO(0, exec);
6fe7ccc8 367}
81345200 368#endif // ENABLE(JIT)
6fe7ccc8
A
369
370LLINT_SLOW_PATH_DECL(entry_osr)
371{
372 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
373}
374
375LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
376{
81345200 377 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForCall(), "entry_osr_function_for_call", Prologue);
6fe7ccc8
A
378}
379
380LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
381{
81345200 382 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForConstruct(), "entry_osr_function_for_construct", Prologue);
6fe7ccc8
A
383}
384
385LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
386{
81345200 387 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForCall(), "entry_osr_function_for_call_arityCheck", ArityCheck);
6fe7ccc8
A
388}
389
390LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
391{
81345200 392 return entryOSR(exec, pc, jsCast<JSFunction*>(exec->callee())->jsExecutable()->codeBlockForConstruct(), "entry_osr_function_for_construct_arityCheck", ArityCheck);
6fe7ccc8
A
393}
394
395LLINT_SLOW_PATH_DECL(loop_osr)
396{
397 CodeBlock* codeBlock = exec->codeBlock();
81345200
A
398
399#if ENABLE(JIT)
400 if (Options::verboseOSR()) {
401 dataLog(
402 *codeBlock, ": Entered loop_osr with executeCounter = ",
403 codeBlock->llintExecuteCounter(), "\n");
404 }
6fe7ccc8
A
405
406 if (!shouldJIT(exec)) {
407 codeBlock->dontJITAnytimeSoon();
81345200 408 LLINT_RETURN_TWO(0, 0);
6fe7ccc8
A
409 }
410
411 if (!jitCompileAndSetHeuristics(codeBlock, exec))
81345200 412 LLINT_RETURN_TWO(0, 0);
6fe7ccc8 413
81345200 414 ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
6fe7ccc8
A
415
416 Vector<BytecodeAndMachineOffset> map;
417 codeBlock->jitCodeMap()->decode(map);
93a37866 418 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
6fe7ccc8
A
419 ASSERT(mapping);
420 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
421
81345200 422 void* jumpTarget = codeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
6fe7ccc8
A
423 ASSERT(jumpTarget);
424
81345200
A
425 LLINT_RETURN_TWO(jumpTarget, exec->topOfFrame());
426#else // ENABLE(JIT)
427 UNUSED_PARAM(pc);
428 codeBlock->dontJITAnytimeSoon();
429 LLINT_RETURN_TWO(0, 0);
430#endif // ENABLE(JIT)
6fe7ccc8
A
431}
432
433LLINT_SLOW_PATH_DECL(replace)
434{
435 CodeBlock* codeBlock = exec->codeBlock();
81345200
A
436
437#if ENABLE(JIT)
438 if (Options::verboseOSR()) {
439 dataLog(
440 *codeBlock, ": Entered replace with executeCounter = ",
441 codeBlock->llintExecuteCounter(), "\n");
442 }
6fe7ccc8
A
443
444 if (shouldJIT(exec))
445 jitCompileAndSetHeuristics(codeBlock, exec);
446 else
447 codeBlock->dontJITAnytimeSoon();
448 LLINT_END_IMPL();
81345200
A
449#else // ENABLE(JIT)
450 codeBlock->dontJITAnytimeSoon();
451 LLINT_END_IMPL();
93a37866 452#endif // ENABLE(JIT)
81345200 453}
6fe7ccc8 454
93a37866 455LLINT_SLOW_PATH_DECL(stack_check)
6fe7ccc8
A
456{
457 LLINT_BEGIN();
458#if LLINT_SLOW_PATH_TRACING
93a37866
A
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);
81345200 463
ed1e77d3 464#if ENABLE(JIT)
81345200 465 dataLogF("Current end is at %p.\n", exec->vm().stackLimit());
ed1e77d3
A
466#else
467 dataLogF("Current end is at %p.\n", exec->vm().jsStackLimit());
6fe7ccc8 468#endif
6fe7ccc8 469
81345200 470#endif
81345200
A
471 // If the stack check succeeds and we don't need to throw the error, then
472 // we'll return 0 instead. The prologue will check for a non-zero value
473 // when determining whether to set the callFrame or not.
474
475 // For JIT enabled builds which uses the C stack, the stack is not growable.
476 // Hence, if we get here, then we know a stack overflow is imminent. So, just
477 // throw the StackOverflowError unconditionally.
478#if !ENABLE(JIT)
479 ASSERT(!vm.interpreter->stack().containsAddress(exec->topOfFrame()));
480 if (LIKELY(vm.interpreter->stack().ensureCapacityFor(exec->topOfFrame())))
481 LLINT_RETURN_TWO(pc, 0);
482#endif
6fe7ccc8 483
81345200
A
484 vm.topCallFrame = exec;
485 ErrorHandlingScope errorScope(vm);
486 CommonSlowPaths::interpreterThrowInCaller(exec, createStackOverflowError(exec));
487 pc = returnToThrowForThrownException(exec);
488 LLINT_RETURN_TWO(pc, exec);
6fe7ccc8
A
489}
490
ed1e77d3 491LLINT_SLOW_PATH_DECL(slow_path_create_lexical_environment)
6fe7ccc8
A
492{
493 LLINT_BEGIN();
494#if LLINT_SLOW_PATH_TRACING
ed1e77d3 495 dataLogF("Creating an lexicalEnvironment, exec = %p!\n", exec);
6fe7ccc8 496#endif
ed1e77d3
A
497 int scopeReg = pc[2].u.operand;
498 JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
499 JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, exec, scope, exec->codeBlock());
500 LLINT_RETURN(JSValue(lexicalEnvironment));
6fe7ccc8
A
501}
502
6fe7ccc8
A
503LLINT_SLOW_PATH_DECL(slow_path_new_object)
504{
505 LLINT_BEGIN();
93a37866 506 LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
6fe7ccc8
A
507}
508
509LLINT_SLOW_PATH_DECL(slow_path_new_array)
510{
511 LLINT_BEGIN();
81345200 512 LLINT_RETURN(constructArrayNegativeIndexed(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
93a37866
A
513}
514
515LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
516{
517 LLINT_BEGIN();
518 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
6fe7ccc8
A
519}
520
521LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
522{
523 LLINT_BEGIN();
93a37866 524 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
6fe7ccc8
A
525}
526
527LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
528{
529 LLINT_BEGIN();
530 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
531 if (!regExp->isValid())
532 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
81345200 533 LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regExp));
6fe7ccc8
A
534}
535
536LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
537{
538 LLINT_BEGIN();
93a37866
A
539
540 JSValue value = LLINT_OP_C(2).jsValue();
541 JSValue baseVal = LLINT_OP_C(3).jsValue();
542 if (baseVal.isObject()) {
543 JSObject* baseObject = asObject(baseVal);
544 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
545 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
4be4e309
A
546 JSValue result = jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value));
547 LLINT_RETURN_WITH_PC_ADJUSTMENT(result, pc[4].u.operand);
93a37866
A
548 }
549 }
ed1e77d3 550 LLINT_THROW(createInvalidInstanceofParameterError(exec, baseVal));
6fe7ccc8
A
551}
552
553LLINT_SLOW_PATH_DECL(slow_path_instanceof)
554{
555 LLINT_BEGIN();
93a37866
A
556 JSValue value = LLINT_OP_C(2).jsValue();
557 JSValue proto = LLINT_OP_C(3).jsValue();
558 ASSERT(!value.isObject() || !proto.isObject());
559 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
6fe7ccc8
A
560}
561
6fe7ccc8
A
562LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
563{
564 LLINT_BEGIN();
565 CodeBlock* codeBlock = exec->codeBlock();
81345200 566 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
6fe7ccc8
A
567 JSValue baseValue = LLINT_OP_C(2).jsValue();
568 PropertySlot slot(baseValue);
569
570 JSValue result = baseValue.get(exec, ident, slot);
571 LLINT_CHECK_EXCEPTION();
572 LLINT_OP(1) = result;
93a37866
A
573
574 if (!LLINT_ALWAYS_ACCESS_SLOW
575 && baseValue.isCell()
6fe7ccc8
A
576 && slot.isCacheable()
577 && slot.slotBase() == baseValue
81345200 578 && slot.isCacheableValue()) {
6fe7ccc8
A
579
580 JSCell* baseCell = baseValue.asCell();
581 Structure* structure = baseCell->structure();
582
583 if (!structure->isUncacheableDictionary()
81345200
A
584 && !structure->typeInfo().prohibitsPropertyCaching()
585 && !structure->typeInfo().newImpurePropertyFiresWatchpoints()) {
586 ConcurrentJITLocker locker(codeBlock->m_lock);
587
6fe7ccc8 588 pc[4].u.structure.set(
93a37866
A
589 vm, codeBlock->ownerExecutable(), structure);
590 if (isInlineOffset(slot.cachedOffset())) {
81345200 591 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id);
93a37866
A
592 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
593 } else {
81345200 594 pc[0].u.opcode = LLInt::getOpcode(op_get_by_id_out_of_line);
93a37866
A
595 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
596 }
6fe7ccc8
A
597 }
598 }
599
93a37866
A
600 if (!LLINT_ALWAYS_ACCESS_SLOW
601 && isJSArray(baseValue)
602 && ident == exec->propertyNames().length) {
81345200 603 pc[0].u.opcode = LLInt::getOpcode(op_get_array_length);
93a37866
A
604 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
605 arrayProfile->observeStructure(baseValue.asCell()->structure());
606 pc[4].u.arrayProfile = arrayProfile;
93a37866
A
607 }
608
6fe7ccc8 609 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
6fe7ccc8
A
610 LLINT_END();
611}
612
613LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
614{
615 LLINT_BEGIN();
616 CodeBlock* codeBlock = exec->codeBlock();
81345200 617 const Identifier& ident = codeBlock->identifier(pc[3].u.operand);
6fe7ccc8
A
618 JSValue baseValue = LLINT_OP(2).jsValue();
619 PropertySlot slot(baseValue);
620 LLINT_RETURN(baseValue.get(exec, ident, slot));
621}
622
623LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
624{
625 LLINT_BEGIN();
626 CodeBlock* codeBlock = exec->codeBlock();
81345200 627 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
6fe7ccc8
A
628
629 JSValue baseValue = LLINT_OP_C(1).jsValue();
81345200 630 PutPropertySlot slot(baseValue, codeBlock->isStrictMode(), codeBlock->putByIdContext());
6fe7ccc8 631 if (pc[8].u.operand)
93a37866 632 asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
6fe7ccc8
A
633 else
634 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
635 LLINT_CHECK_EXCEPTION();
636
93a37866
A
637 if (!LLINT_ALWAYS_ACCESS_SLOW
638 && baseValue.isCell()
81345200 639 && slot.isCacheablePut()) {
6fe7ccc8
A
640
641 JSCell* baseCell = baseValue.asCell();
642 Structure* structure = baseCell->structure();
643
644 if (!structure->isUncacheableDictionary()
645 && !structure->typeInfo().prohibitsPropertyCaching()
646 && baseCell == slot.base()) {
647
648 if (slot.type() == PutPropertySlot::NewProperty) {
81345200
A
649 GCSafeConcurrentJITLocker locker(codeBlock->m_lock, vm.heap);
650
93a37866
A
651 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
652 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
653
6fe7ccc8
A
654 // This is needed because some of the methods we call
655 // below may GC.
81345200 656 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
93a37866 657
ed1e77d3 658 if (normalizePrototypeChain(exec, structure) != InvalidPrototypeChain) {
93a37866
A
659 ASSERT(structure->previousID()->isObject());
660 pc[4].u.structure.set(
661 vm, codeBlock->ownerExecutable(), structure->previousID());
662 if (isInlineOffset(slot.cachedOffset()))
663 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
664 else
665 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
666 pc[6].u.structure.set(
667 vm, codeBlock->ownerExecutable(), structure);
668 StructureChain* chain = structure->prototypeChain(exec);
669 ASSERT(chain);
670 pc[7].u.structureChain.set(
671 vm, codeBlock->ownerExecutable(), chain);
6fe7ccc8 672
93a37866
A
673 if (pc[8].u.operand) {
674 if (isInlineOffset(slot.cachedOffset()))
81345200 675 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct);
93a37866 676 else
81345200 677 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_direct_out_of_line);
93a37866
A
678 } else {
679 if (isInlineOffset(slot.cachedOffset()))
81345200 680 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal);
93a37866 681 else
81345200 682 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_transition_normal_out_of_line);
93a37866
A
683 }
684 }
6fe7ccc8
A
685 }
686 } else {
ed1e77d3 687 structure->didCachePropertyReplacement(vm, slot.cachedOffset());
6fe7ccc8 688 pc[4].u.structure.set(
93a37866
A
689 vm, codeBlock->ownerExecutable(), structure);
690 if (isInlineOffset(slot.cachedOffset())) {
81345200 691 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id);
93a37866
A
692 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
693 } else {
81345200 694 pc[0].u.opcode = LLInt::getOpcode(op_put_by_id_out_of_line);
93a37866
A
695 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
696 }
6fe7ccc8
A
697 }
698 }
699 }
700
701 LLINT_END();
702}
703
704LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
705{
706 LLINT_BEGIN();
707 CodeBlock* codeBlock = exec->codeBlock();
708 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
709 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
710 LLINT_CHECK_EXCEPTION();
711 if (!couldDelete && codeBlock->isStrictMode())
712 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
713 LLINT_RETURN(jsBoolean(couldDelete));
714}
715
716inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
717{
718 if (LIKELY(baseValue.isCell() && subscript.isString())) {
81345200
A
719 VM& vm = exec->vm();
720 Structure& structure = *baseValue.asCell()->structure(vm);
721 if (JSCell::canUseFastGetOwnProperty(structure)) {
ed1e77d3
A
722 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(subscript)->toExistingAtomicString(exec)) {
723 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
724 return result;
725 }
81345200 726 }
6fe7ccc8
A
727 }
728
729 if (subscript.isUInt32()) {
730 uint32_t i = subscript.asUInt32();
731 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
732 return asString(baseValue)->getIndex(exec, i);
733
734 return baseValue.get(exec, i);
735 }
93a37866 736
ed1e77d3
A
737 baseValue.requireObjectCoercible(exec);
738 if (exec->hadException())
739 return jsUndefined();
740 auto property = subscript.toPropertyKey(exec);
741 if (exec->hadException())
742 return jsUndefined();
6fe7ccc8
A
743 return baseValue.get(exec, property);
744}
745
746LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
747{
748 LLINT_BEGIN();
749 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
750}
751
6fe7ccc8
A
752LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
753{
754 LLINT_BEGIN();
755
756 JSValue baseValue = LLINT_OP_C(1).jsValue();
757 JSValue subscript = LLINT_OP_C(2).jsValue();
758 JSValue value = LLINT_OP_C(3).jsValue();
759
760 if (LIKELY(subscript.isUInt32())) {
761 uint32_t i = subscript.asUInt32();
93a37866
A
762 if (baseValue.isObject()) {
763 JSObject* object = asObject(baseValue);
764 if (object->canSetIndexQuickly(i))
765 object->setIndexQuickly(vm, i, value);
6fe7ccc8 766 else
93a37866 767 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
6fe7ccc8
A
768 LLINT_END();
769 }
770 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
771 LLINT_END();
772 }
93a37866 773
ed1e77d3 774 auto property = subscript.toPropertyKey(exec);
6fe7ccc8 775 LLINT_CHECK_EXCEPTION();
81345200 776 PutPropertySlot slot(baseValue, exec->codeBlock()->isStrictMode());
6fe7ccc8
A
777 baseValue.put(exec, property, value, slot);
778 LLINT_END();
779}
780
81345200
A
781LLINT_SLOW_PATH_DECL(slow_path_put_by_val_direct)
782{
783 LLINT_BEGIN();
784
785 JSValue baseValue = LLINT_OP_C(1).jsValue();
786 JSValue subscript = LLINT_OP_C(2).jsValue();
787 JSValue value = LLINT_OP_C(3).jsValue();
788 RELEASE_ASSERT(baseValue.isObject());
789 JSObject* baseObject = asObject(baseValue);
ed1e77d3 790 bool isStrictMode = exec->codeBlock()->isStrictMode();
81345200 791 if (LIKELY(subscript.isUInt32())) {
ed1e77d3
A
792 // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
793 ASSERT(isIndex(subscript.asUInt32()));
794 baseObject->putDirectIndex(exec, subscript.asUInt32(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
795 LLINT_END();
796 }
797
798 if (subscript.isDouble()) {
799 double subscriptAsDouble = subscript.asDouble();
800 uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble);
801 if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
802 baseObject->putDirectIndex(exec, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
803 LLINT_END();
81345200
A
804 }
805 }
ed1e77d3
A
806
807 // Don't put to an object if toString threw an exception.
808 auto property = subscript.toPropertyKey(exec);
809 if (exec->vm().exception())
810 LLINT_END();
811
812 if (Optional<uint32_t> index = parseIndex(property))
813 baseObject->putDirectIndex(exec, index.value(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
814 else {
815 PutPropertySlot slot(baseObject, isStrictMode);
816 baseObject->putDirect(exec->vm(), property, value, slot);
817 }
81345200
A
818 LLINT_END();
819}
820
6fe7ccc8
A
821LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
822{
823 LLINT_BEGIN();
824 JSValue baseValue = LLINT_OP_C(2).jsValue();
825 JSObject* baseObject = baseValue.toObject(exec);
826
827 JSValue subscript = LLINT_OP_C(3).jsValue();
828
829 bool couldDelete;
830
831 uint32_t i;
832 if (subscript.getUInt32(i))
833 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
834 else {
835 LLINT_CHECK_EXCEPTION();
ed1e77d3 836 auto property = subscript.toPropertyKey(exec);
6fe7ccc8
A
837 LLINT_CHECK_EXCEPTION();
838 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
839 }
840
841 if (!couldDelete && exec->codeBlock()->isStrictMode())
842 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
843
844 LLINT_RETURN(jsBoolean(couldDelete));
845}
846
847LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
848{
849 LLINT_BEGIN();
850 JSValue arrayValue = LLINT_OP_C(1).jsValue();
851 ASSERT(isJSArray(arrayValue));
93a37866 852 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
6fe7ccc8
A
853 LLINT_END();
854}
855
ed1e77d3
A
856LLINT_SLOW_PATH_DECL(slow_path_put_getter_by_id)
857{
858 LLINT_BEGIN();
859 ASSERT(LLINT_OP(1).jsValue().isObject());
860 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
861
862 JSValue getter = LLINT_OP(3).jsValue();
863 ASSERT(getter.isObject());
864
865 baseObj->putGetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(getter));
866 LLINT_END();
867}
868
869LLINT_SLOW_PATH_DECL(slow_path_put_setter_by_id)
870{
871 LLINT_BEGIN();
872 ASSERT(LLINT_OP(1).jsValue().isObject());
873 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
874
875 JSValue setter = LLINT_OP(3).jsValue();
876 ASSERT(setter.isObject());
877
878 baseObj->putSetter(exec, exec->codeBlock()->identifier(pc[2].u.operand), asObject(setter));
879 LLINT_END();
880}
881
6fe7ccc8
A
882LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
883{
884 LLINT_BEGIN();
885 ASSERT(LLINT_OP(1).jsValue().isObject());
886 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
887
ed1e77d3 888 GetterSetter* accessor = GetterSetter::create(vm, exec->lexicalGlobalObject());
6fe7ccc8
A
889 LLINT_CHECK_EXCEPTION();
890
891 JSValue getter = LLINT_OP(3).jsValue();
892 JSValue setter = LLINT_OP(4).jsValue();
893 ASSERT(getter.isObject() || getter.isUndefined());
894 ASSERT(setter.isObject() || setter.isUndefined());
895 ASSERT(getter.isObject() || setter.isObject());
896
897 if (!getter.isUndefined())
ed1e77d3 898 accessor->setGetter(vm, exec->lexicalGlobalObject(), asObject(getter));
6fe7ccc8 899 if (!setter.isUndefined())
ed1e77d3 900 accessor->setSetter(vm, exec->lexicalGlobalObject(), asObject(setter));
6fe7ccc8 901 baseObj->putDirectAccessor(
93a37866 902 exec,
6fe7ccc8
A
903 exec->codeBlock()->identifier(pc[2].u.operand),
904 accessor, Accessor);
905 LLINT_END();
906}
907
6fe7ccc8
A
908LLINT_SLOW_PATH_DECL(slow_path_jtrue)
909{
910 LLINT_BEGIN();
911 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
912}
913
914LLINT_SLOW_PATH_DECL(slow_path_jfalse)
915{
916 LLINT_BEGIN();
917 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
918}
919
920LLINT_SLOW_PATH_DECL(slow_path_jless)
921{
922 LLINT_BEGIN();
923 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
924}
925
926LLINT_SLOW_PATH_DECL(slow_path_jnless)
927{
928 LLINT_BEGIN();
929 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
930}
931
932LLINT_SLOW_PATH_DECL(slow_path_jgreater)
933{
934 LLINT_BEGIN();
935 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
936}
937
938LLINT_SLOW_PATH_DECL(slow_path_jngreater)
939{
940 LLINT_BEGIN();
941 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
942}
943
944LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
945{
946 LLINT_BEGIN();
947 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
948}
949
950LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
951{
952 LLINT_BEGIN();
953 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
954}
955
956LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
957{
958 LLINT_BEGIN();
959 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
960}
961
962LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
963{
964 LLINT_BEGIN();
965 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
966}
967
968LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
969{
970 LLINT_BEGIN();
971 JSValue scrutinee = LLINT_OP_C(3).jsValue();
972 ASSERT(scrutinee.isDouble());
973 double value = scrutinee.asDouble();
974 int32_t intValue = static_cast<int32_t>(value);
975 int defaultOffset = pc[2].u.operand;
976 if (value == intValue) {
977 CodeBlock* codeBlock = exec->codeBlock();
81345200 978 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
6fe7ccc8
A
979 } else
980 pc += defaultOffset;
981 LLINT_END();
982}
983
984LLINT_SLOW_PATH_DECL(slow_path_switch_char)
985{
986 LLINT_BEGIN();
987 JSValue scrutinee = LLINT_OP_C(3).jsValue();
988 ASSERT(scrutinee.isString());
989 JSString* string = asString(scrutinee);
990 ASSERT(string->length() == 1);
991 int defaultOffset = pc[2].u.operand;
992 StringImpl* impl = string->value(exec).impl();
993 CodeBlock* codeBlock = exec->codeBlock();
81345200 994 pc += codeBlock->switchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
6fe7ccc8
A
995 LLINT_END();
996}
997
998LLINT_SLOW_PATH_DECL(slow_path_switch_string)
999{
1000 LLINT_BEGIN();
1001 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1002 int defaultOffset = pc[2].u.operand;
1003 if (!scrutinee.isString())
1004 pc += defaultOffset;
1005 else {
1006 CodeBlock* codeBlock = exec->codeBlock();
1007 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1008 }
1009 LLINT_END();
1010}
1011
1012LLINT_SLOW_PATH_DECL(slow_path_new_func)
1013{
1014 LLINT_BEGIN();
1015 CodeBlock* codeBlock = exec->codeBlock();
81345200 1016 ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsActivation() || exec->hasActivation());
ed1e77d3 1017 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
6fe7ccc8 1018#if LLINT_SLOW_PATH_TRACING
93a37866 1019 dataLogF("Creating function!\n");
6fe7ccc8 1020#endif
ed1e77d3 1021 LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
6fe7ccc8
A
1022}
1023
1024LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1025{
1026 LLINT_BEGIN();
1027 CodeBlock* codeBlock = exec->codeBlock();
ed1e77d3
A
1028 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
1029 FunctionExecutable* function = codeBlock->functionExpr(pc[3].u.operand);
1030 JSFunction* func = JSFunction::create(vm, function, scope);
6fe7ccc8
A
1031
1032 LLINT_RETURN(func);
1033}
1034
1035static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1036{
81345200
A
1037 UNUSED_PARAM(pc);
1038
93a37866
A
1039#if LLINT_SLOW_PATH_TRACING
1040 dataLog("Performing host call.\n");
1041#endif
1042
6fe7ccc8 1043 ExecState* exec = execCallee->callerFrame();
93a37866 1044 VM& vm = exec->vm();
6fe7ccc8 1045
6fe7ccc8
A
1046 execCallee->setCodeBlock(0);
1047 execCallee->clearReturnPC();
1048
1049 if (kind == CodeForCall) {
1050 CallData callData;
1051 CallType callType = getCallData(callee, callData);
1052
1053 ASSERT(callType != CallTypeJS);
1054
1055 if (callType == CallTypeHost) {
93a37866 1056 NativeCallFrameTracer tracer(&vm, execCallee);
6fe7ccc8 1057 execCallee->setCallee(asObject(callee));
93a37866 1058 vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
6fe7ccc8 1059
ed1e77d3 1060 LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
6fe7ccc8
A
1061 }
1062
1063#if LLINT_SLOW_PATH_TRACING
93a37866 1064 dataLog("Call callee is not a function: ", callee, "\n");
6fe7ccc8
A
1065#endif
1066
1067 ASSERT(callType == CallTypeNone);
81345200 1068 LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
6fe7ccc8
A
1069 }
1070
1071 ASSERT(kind == CodeForConstruct);
1072
1073 ConstructData constructData;
1074 ConstructType constructType = getConstructData(callee, constructData);
1075
1076 ASSERT(constructType != ConstructTypeJS);
1077
1078 if (constructType == ConstructTypeHost) {
93a37866 1079 NativeCallFrameTracer tracer(&vm, execCallee);
6fe7ccc8 1080 execCallee->setCallee(asObject(callee));
93a37866 1081 vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
6fe7ccc8 1082
ed1e77d3 1083 LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
6fe7ccc8
A
1084 }
1085
1086#if LLINT_SLOW_PATH_TRACING
93a37866 1087 dataLog("Constructor callee is not a function: ", callee, "\n");
6fe7ccc8
A
1088#endif
1089
1090 ASSERT(constructType == ConstructTypeNone);
81345200 1091 LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
6fe7ccc8
A
1092}
1093
1094inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1095{
ed1e77d3
A
1096 ExecState* exec = execCallee->callerFrame();
1097
6fe7ccc8 1098#if LLINT_SLOW_PATH_TRACING
ed1e77d3 1099 dataLogF("Performing call with recorded PC = %p\n", exec->currentVPC());
6fe7ccc8 1100#endif
ed1e77d3 1101
6fe7ccc8
A
1102 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1103 if (!calleeAsFunctionCell)
1104 return handleHostCall(execCallee, pc, calleeAsValue, kind);
1105
1106 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
93a37866
A
1107 JSScope* scope = callee->scopeUnchecked();
1108 VM& vm = *scope->vm();
6fe7ccc8
A
1109 ExecutableBase* executable = callee->executable();
1110
1111 MacroAssemblerCodePtr codePtr;
1112 CodeBlock* codeBlock = 0;
1113 if (executable->isHostFunction())
81345200 1114 codePtr = executable->entrypointFor(vm, kind, MustCheckArity, RegisterPreservationNotRequired);
6fe7ccc8
A
1115 else {
1116 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
ed1e77d3
A
1117
1118 if (!isCall(kind) && functionExecutable->isBuiltinFunction())
1119 LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
1120
1121 JSObject* error = functionExecutable->prepareForExecution(execCallee, callee, scope, kind);
6fe7ccc8 1122 if (error)
ed1e77d3 1123 LLINT_CALL_THROW(exec, error);
81345200 1124 codeBlock = functionExecutable->codeBlockFor(kind);
6fe7ccc8 1125 ASSERT(codeBlock);
81345200 1126 ArityCheckMode arity;
6fe7ccc8 1127 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
81345200 1128 arity = MustCheckArity;
6fe7ccc8 1129 else
81345200
A
1130 arity = ArityCheckNotRequired;
1131 codePtr = functionExecutable->entrypointFor(vm, kind, arity, RegisterPreservationNotRequired);
6fe7ccc8
A
1132 }
1133
81345200
A
1134 ASSERT(!!codePtr);
1135
93a37866 1136 if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
ed1e77d3 1137 CodeBlock* callerCodeBlock = exec->codeBlock();
81345200
A
1138
1139 ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1140
6fe7ccc8
A
1141 if (callLinkInfo->isOnList())
1142 callLinkInfo->remove();
81345200
A
1143 callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
1144 callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
6fe7ccc8
A
1145 callLinkInfo->machineCodeTarget = codePtr;
1146 if (codeBlock)
ed1e77d3 1147 codeBlock->linkIncomingCall(exec, callLinkInfo);
6fe7ccc8 1148 }
93a37866 1149
ed1e77d3 1150 LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
6fe7ccc8
A
1151}
1152
1153inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1154{
1155 // This needs to:
1156 // - Set up a call frame.
1157 // - Figure out what to call and compile it if necessary.
1158 // - If possible, link the call's inline cache.
1159 // - Return a tuple of machine code address to call and the new call frame.
1160
81345200 1161 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
6fe7ccc8 1162
81345200 1163 ExecState* execCallee = exec - pc[4].u.operand;
6fe7ccc8 1164
81345200 1165 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
93a37866 1166 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
6fe7ccc8
A
1167 execCallee->setCallerFrame(exec);
1168
81345200
A
1169 ASSERT(pc[5].u.callLinkInfo);
1170 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[5].u.callLinkInfo);
6fe7ccc8
A
1171}
1172
1173LLINT_SLOW_PATH_DECL(slow_path_call)
1174{
1175 LLINT_BEGIN_NO_SET_PC();
1176 return genericCall(exec, pc, CodeForCall);
1177}
1178
1179LLINT_SLOW_PATH_DECL(slow_path_construct)
1180{
1181 LLINT_BEGIN_NO_SET_PC();
1182 return genericCall(exec, pc, CodeForConstruct);
1183}
1184
81345200 1185LLINT_SLOW_PATH_DECL(slow_path_size_frame_for_varargs)
6fe7ccc8
A
1186{
1187 LLINT_BEGIN();
1188 // This needs to:
1189 // - Set up a call frame while respecting the variable arguments.
81345200 1190
ed1e77d3
A
1191 unsigned numUsedStackSlots = -pc[5].u.operand;
1192 unsigned length = sizeFrameForVarargs(exec, &vm.interpreter->stack(),
1193 LLINT_OP_C(4).jsValue(), numUsedStackSlots, pc[6].u.operand);
1194 LLINT_CALL_CHECK_EXCEPTION(exec, exec);
81345200 1195
ed1e77d3
A
1196 ExecState* execCallee = calleeFrameForVarargs(exec, numUsedStackSlots, length + 1);
1197 vm.varargsLength = length;
81345200
A
1198 vm.newCallFrameReturnValue = execCallee;
1199
1200 LLINT_RETURN_CALLEE_FRAME(execCallee);
1201}
1202
1203LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1204{
1205 LLINT_BEGIN_NO_SET_PC();
1206 // This needs to:
6fe7ccc8
A
1207 // - Figure out what to call and compile it if necessary.
1208 // - Return a tuple of machine code address to call and the new call frame.
1209
81345200 1210 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
6fe7ccc8 1211
81345200
A
1212 ExecState* execCallee = vm.newCallFrameReturnValue;
1213
ed1e77d3
A
1214 setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
1215 LLINT_CALL_CHECK_EXCEPTION(exec, exec);
6fe7ccc8 1216
93a37866 1217 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
6fe7ccc8 1218 execCallee->setCallerFrame(exec);
81345200 1219 exec->setCurrentVPC(pc);
6fe7ccc8
A
1220
1221 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1222}
81345200
A
1223
1224LLINT_SLOW_PATH_DECL(slow_path_construct_varargs)
1225{
1226 LLINT_BEGIN_NO_SET_PC();
1227 // This needs to:
1228 // - Figure out what to call and compile it if necessary.
1229 // - Return a tuple of machine code address to call and the new call frame.
1230
1231 JSValue calleeAsValue = LLINT_OP_C(2).jsValue();
1232
1233 ExecState* execCallee = vm.newCallFrameReturnValue;
1234
ed1e77d3
A
1235 setupVarargsFrameAndSetThis(exec, execCallee, LLINT_OP_C(3).jsValue(), LLINT_OP_C(4).jsValue(), pc[6].u.operand, vm.varargsLength);
1236 LLINT_CALL_CHECK_EXCEPTION(exec, exec);
81345200
A
1237
1238 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1239 execCallee->setCallerFrame(exec);
1240 exec->setCurrentVPC(pc);
1241
1242 return setUpCall(execCallee, pc, CodeForConstruct, calleeAsValue);
1243}
1244
6fe7ccc8
A
1245LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1246{
1247 LLINT_BEGIN_NO_SET_PC();
81345200 1248 JSValue calleeAsValue = LLINT_OP(2).jsValue();
6fe7ccc8 1249
81345200 1250 ExecState* execCallee = exec - pc[4].u.operand;
6fe7ccc8 1251
81345200 1252 execCallee->setArgumentCountIncludingThis(pc[3].u.operand);
6fe7ccc8 1253 execCallee->setCallerFrame(exec);
93a37866 1254 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
93a37866 1255 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
6fe7ccc8 1256 execCallee->setCodeBlock(0);
81345200 1257 exec->setCurrentVPC(pc);
6fe7ccc8
A
1258
1259 if (!isHostFunction(calleeAsValue, globalFuncEval))
1260 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1261
93a37866 1262 vm.hostCallReturnValue = eval(execCallee);
ed1e77d3 1263 LLINT_CALL_RETURN(exec, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
6fe7ccc8
A
1264}
1265
1266LLINT_SLOW_PATH_DECL(slow_path_strcat)
1267{
1268 LLINT_BEGIN();
81345200 1269 LLINT_RETURN(jsStringFromRegisterArray(exec, &LLINT_OP(2), pc[3].u.operand));
6fe7ccc8
A
1270}
1271
1272LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1273{
1274 LLINT_BEGIN();
1275 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1276}
1277
93a37866 1278LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
6fe7ccc8
A
1279{
1280 LLINT_BEGIN();
ed1e77d3 1281 JSValue v = LLINT_OP_C(2).jsValue();
6fe7ccc8
A
1282 JSObject* o = v.toObject(exec);
1283 LLINT_CHECK_EXCEPTION();
ed1e77d3
A
1284
1285 int scopeReg = pc[1].u.operand;
1286 JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
1287 exec->uncheckedR(scopeReg) = JSWithScope::create(exec, o, currentScope);
6fe7ccc8
A
1288
1289 LLINT_END();
1290}
1291
1292LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1293{
1294 LLINT_BEGIN();
ed1e77d3
A
1295 int scopeReg = pc[1].u.operand;
1296 JSScope* scope = exec->uncheckedR(scopeReg).Register::scope();
1297 exec->uncheckedR(scopeReg) = scope->next();
6fe7ccc8
A
1298 LLINT_END();
1299}
1300
93a37866 1301LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
6fe7ccc8
A
1302{
1303 LLINT_BEGIN();
ed1e77d3
A
1304 int scopeReg = pc[1].u.operand;
1305 JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
1306 JSValue value = LLINT_OP_C(2).jsValue();
1307 SymbolTable* symbolTable = jsCast<SymbolTable*>(LLINT_OP_C(3).jsValue());
1308 JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[4].u.operand);
1309 JSNameScope* scope = JSNameScope::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, value, type);
1310 exec->uncheckedR(scopeReg) = scope;
93a37866 1311 LLINT_END();
6fe7ccc8
A
1312}
1313
1314LLINT_SLOW_PATH_DECL(slow_path_throw)
1315{
1316 LLINT_BEGIN();
1317 LLINT_THROW(LLINT_OP_C(1).jsValue());
1318}
1319
93a37866 1320LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
6fe7ccc8
A
1321{
1322 LLINT_BEGIN();
ed1e77d3
A
1323 JSValue errorMessageValue = LLINT_OP_C(1).jsValue();
1324 RELEASE_ASSERT(errorMessageValue.isString());
1325 String errorMessage = asString(errorMessageValue)->value(exec);
93a37866 1326 if (pc[2].u.operand)
ed1e77d3 1327 LLINT_THROW(createReferenceError(exec, errorMessage));
93a37866 1328 else
ed1e77d3 1329 LLINT_THROW(createTypeError(exec, errorMessage));
93a37866
A
1330}
1331
1332LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1333{
1334 LLINT_BEGIN_NO_SET_PC();
81345200
A
1335 ASSERT(vm.watchdog);
1336 if (UNLIKELY(vm.watchdog->didFire(exec)))
93a37866
A
1337 LLINT_THROW(createTerminatedExecutionException(&vm));
1338 LLINT_RETURN_TWO(0, exec);
6fe7ccc8
A
1339}
1340
1341LLINT_SLOW_PATH_DECL(slow_path_debug)
1342{
1343 LLINT_BEGIN();
1344 int debugHookID = pc[1].u.operand;
81345200 1345 vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID));
6fe7ccc8
A
1346
1347 LLINT_END();
1348}
1349
1350LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1351{
1352 LLINT_BEGIN();
93a37866
A
1353 if (LegacyProfiler* profiler = vm.enabledProfiler())
1354 profiler->willExecute(exec, LLINT_OP(1).jsValue());
6fe7ccc8
A
1355 LLINT_END();
1356}
1357
1358LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1359{
1360 LLINT_BEGIN();
93a37866
A
1361 if (LegacyProfiler* profiler = vm.enabledProfiler())
1362 profiler->didExecute(exec, LLINT_OP(1).jsValue());
6fe7ccc8
A
1363 LLINT_END();
1364}
1365
81345200
A
1366LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
1367{
1368 LLINT_BEGIN_NO_SET_PC();
ed1e77d3 1369 genericUnwind(&vm, exec);
81345200
A
1370 LLINT_END_IMPL();
1371}
1372
1373LLINT_SLOW_PATH_DECL(slow_path_resolve_scope)
1374{
1375 LLINT_BEGIN();
ed1e77d3
A
1376 const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1377 JSScope* scope = LLINT_OP(2).Register::scope();
1378 LLINT_RETURN(JSScope::resolve(exec, scope, ident));
81345200
A
1379}
1380
1381LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
1382{
1383 LLINT_BEGIN();
ed1e77d3 1384
81345200
A
1385 const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
1386 JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
1387 ResolveModeAndType modeAndType(pc[4].u.operand);
1388
1389 PropertySlot slot(scope);
1390 if (!scope->getPropertySlot(exec, ident, slot)) {
1391 if (modeAndType.mode() == ThrowIfNotFound)
1392 LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
1393 LLINT_RETURN(jsUndefined());
1394 }
1395
1396 // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
1397 if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
1398 if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
1399 CodeBlock* codeBlock = exec->codeBlock();
ed1e77d3
A
1400 Structure* structure = scope->structure(vm);
1401 {
1402 ConcurrentJITLocker locker(codeBlock->m_lock);
1403 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
1404 pc[6].u.operand = slot.cachedOffset();
1405 }
1406 structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
81345200
A
1407 }
1408 }
1409
1410 LLINT_RETURN(slot.getValue(exec, ident));
1411}
1412
1413LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
6fe7ccc8
A
1414{
1415 LLINT_BEGIN();
ed1e77d3 1416
81345200
A
1417 CodeBlock* codeBlock = exec->codeBlock();
1418 const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
1419 JSObject* scope = jsCast<JSObject*>(LLINT_OP(1).jsValue());
1420 JSValue value = LLINT_OP_C(3).jsValue();
1421 ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
ed1e77d3
A
1422 if (modeAndType.type() == LocalClosureVar) {
1423 JSLexicalEnvironment* environment = jsCast<JSLexicalEnvironment*>(scope);
1424 environment->variableAt(ScopeOffset(pc[6].u.operand)).set(vm, environment, value);
1425
1426 // Have to do this *after* the write, because if this puts the set into IsWatched, then we need
1427 // to have already changed the value of the variable. Otherwise we might watch and constant-fold
1428 // to the Undefined value from before the assignment.
1429 if (WatchpointSet* set = pc[5].u.watchpointSet)
1430 set->touch("Executed op_put_scope<LocalClosureVar>");
1431 LLINT_END();
1432 }
81345200
A
1433
1434 if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
1435 LLINT_THROW(createUndefinedVariableError(exec, ident));
1436
1437 PutPropertySlot slot(scope, codeBlock->isStrictMode());
1438 scope->methodTable()->put(scope, exec, ident, value, slot);
ed1e77d3
A
1439
1440 CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
81345200 1441
6fe7ccc8
A
1442 LLINT_END();
1443}
1444
81345200
A
1445extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
1446{
1447 ExecState* exec = vm->topCallFrame;
1448 if (!exec)
ed1e77d3 1449 exec = protoFrame->callee()->globalObject()->globalExec();
81345200
A
1450 throwStackOverflowError(exec);
1451 return encodeResult(0, 0);
1452}
6fe7ccc8 1453
81345200
A
1454#if !ENABLE(JIT)
1455extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM* vm, Register* newTopOfStack)
1456{
1457 bool success = vm->interpreter->stack().ensureCapacityFor(newTopOfStack);
1458 return encodeResult(reinterpret_cast<void*>(success), 0);
1459}
1460#endif
1461
1462extern "C" void llint_write_barrier_slow(ExecState* exec, JSCell* cell)
1463{
1464 VM& vm = exec->vm();
1465 vm.heap.writeBarrier(cell);
1466}
1467
1468extern "C" NO_RETURN_DUE_TO_CRASH void llint_crash()
1469{
1470 CRASH();
1471}
1472
1473} } // namespace JSC::LLInt