]> git.saurik.com Git - apple/javascriptcore.git/blob - llint/LLIntSlowPaths.cpp
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / llint / LLIntSlowPaths.cpp
1 /*
2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
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"
28
29 #if ENABLE(LLINT)
30
31 #include "Arguments.h"
32 #include "ArrayConstructor.h"
33 #include "CallFrame.h"
34 #include "CommonSlowPaths.h"
35 #include "GetterSetter.h"
36 #include "HostCallReturnValue.h"
37 #include "Interpreter.h"
38 #include "JIT.h"
39 #include "JITDriver.h"
40 #include "JSActivation.h"
41 #include "JSCJSValue.h"
42 #include "JSGlobalObjectFunctions.h"
43 #include "JSNameScope.h"
44 #include "JSPropertyNameIterator.h"
45 #include "JSString.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>
54
55 namespace JSC { namespace LLInt {
56
57 #define LLINT_BEGIN_NO_SET_PC() \
58 VM& vm = exec->vm(); \
59 NativeCallFrameTracer tracer(&vm, exec)
60
61 #ifndef NDEBUG
62 #define LLINT_SET_PC_FOR_STUBS() do { \
63 exec->codeBlock()->bytecodeOffset(pc); \
64 exec->setCurrentVPC(pc + 1); \
65 } while (false)
66 #else
67 #define LLINT_SET_PC_FOR_STUBS() do { \
68 exec->setCurrentVPC(pc + 1); \
69 } while (false)
70 #endif
71
72 #define LLINT_BEGIN() \
73 LLINT_BEGIN_NO_SET_PC(); \
74 LLINT_SET_PC_FOR_STUBS()
75
76 #define LLINT_OP(index) (exec->uncheckedR(pc[index].u.operand))
77 #define LLINT_OP_C(index) (exec->r(pc[index].u.operand))
78
79 #define LLINT_RETURN_TWO(first, second) do { \
80 return encodeResult(first, second); \
81 } while (false)
82
83 #define LLINT_END_IMPL() LLINT_RETURN_TWO(pc, exec)
84
85 #define LLINT_THROW(exceptionToThrow) do { \
86 vm.exception = (exceptionToThrow); \
87 pc = returnToThrow(exec, pc); \
88 LLINT_END_IMPL(); \
89 } while (false)
90
91 #define LLINT_CHECK_EXCEPTION() do { \
92 if (UNLIKELY(vm.exception)) { \
93 pc = returnToThrow(exec, pc); \
94 LLINT_END_IMPL(); \
95 } \
96 } while (false)
97
98 #define LLINT_END() do { \
99 LLINT_CHECK_EXCEPTION(); \
100 LLINT_END_IMPL(); \
101 } while (false)
102
103 #define LLINT_BRANCH(opcode, condition) do { \
104 bool __b_condition = (condition); \
105 LLINT_CHECK_EXCEPTION(); \
106 if (__b_condition) \
107 pc += pc[OPCODE_LENGTH(opcode) - 1].u.operand; \
108 else \
109 pc += OPCODE_LENGTH(opcode); \
110 LLINT_END_IMPL(); \
111 } while (false)
112
113 #define LLINT_RETURN(value) do { \
114 JSValue __r_returnValue = (value); \
115 LLINT_CHECK_EXCEPTION(); \
116 LLINT_OP(1) = __r_returnValue; \
117 LLINT_END_IMPL(); \
118 } while (false)
119
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); \
126 LLINT_END_IMPL(); \
127 } while (false)
128
129 #define LLINT_PROFILE_VALUE(opcode, value) do { \
130 pc[OPCODE_LENGTH(opcode) - 1].u.profile->m_buckets[0] = \
131 JSValue::encode(value); \
132 } while (false)
133
134 #else // ENABLE(VALUE_PROFILER)
135 #define LLINT_RETURN_PROFILED(opcode, value) LLINT_RETURN(value)
136
137 #define LLINT_PROFILE_VALUE(opcode, value) do { } while (false)
138
139 #endif // ENABLE(VALUE_PROFILER)
140
141 #define LLINT_CALL_END_IMPL(exec, callTarget) LLINT_RETURN_TWO((callTarget), (exec))
142
143 #define LLINT_CALL_THROW(exec, pc, exceptionToThrow) do { \
144 ExecState* __ct_exec = (exec); \
145 Instruction* __ct_pc = (pc); \
146 vm.exception = (exceptionToThrow); \
147 LLINT_CALL_END_IMPL(__ct_exec, callToThrow(__ct_exec, __ct_pc)); \
148 } while (false)
149
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)); \
155 } while (false)
156
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); \
163 } while (false)
164
165 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
166 {
167 LLINT_BEGIN();
168 dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
169 exec->codeBlock(),
170 exec,
171 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
172 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
173 fromWhere,
174 operand,
175 pc[operand].u.operand);
176 LLINT_END();
177 }
178
179 extern "C" SlowPathReturnType llint_trace_value(ExecState* exec, Instruction* pc, int fromWhere, int operand)
180 {
181 JSValue value = LLINT_OP_C(operand).jsValue();
182 union {
183 struct {
184 uint32_t tag;
185 uint32_t payload;
186 } bits;
187 EncodedJSValue asValue;
188 } u;
189 u.asValue = JSValue::encode(value);
190 dataLogF(
191 "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
192 exec->codeBlock(),
193 exec,
194 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
195 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
196 fromWhere,
197 operand,
198 pc[operand].u.operand,
199 u.bits.tag,
200 u.bits.payload,
201 toCString(value).data());
202 LLINT_END_IMPL();
203 }
204
205 LLINT_SLOW_PATH_DECL(trace_prologue)
206 {
207 dataLogF("%p / %p: in prologue.\n", exec->codeBlock(), exec);
208 LLINT_END_IMPL();
209 }
210
211 static void traceFunctionPrologue(ExecState* exec, const char* comment, CodeSpecializationKind kind)
212 {
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());
220 }
221
222 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_call)
223 {
224 traceFunctionPrologue(exec, "call prologue", CodeForCall);
225 LLINT_END_IMPL();
226 }
227
228 LLINT_SLOW_PATH_DECL(trace_prologue_function_for_construct)
229 {
230 traceFunctionPrologue(exec, "construct prologue", CodeForConstruct);
231 LLINT_END_IMPL();
232 }
233
234 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_call)
235 {
236 traceFunctionPrologue(exec, "call arity check", CodeForCall);
237 LLINT_END_IMPL();
238 }
239
240 LLINT_SLOW_PATH_DECL(trace_arityCheck_for_construct)
241 {
242 traceFunctionPrologue(exec, "construct arity check", CodeForConstruct);
243 LLINT_END_IMPL();
244 }
245
246 LLINT_SLOW_PATH_DECL(trace)
247 {
248 dataLogF("%p / %p: executing bc#%zu, %s, scope %p\n",
249 exec->codeBlock(),
250 exec,
251 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
252 opcodeNames[exec->vm().interpreter->getOpcodeID(pc[0].u.opcode)],
253 exec->scope());
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());
257 }
258 LLINT_END_IMPL();
259 }
260
261 LLINT_SLOW_PATH_DECL(special_trace)
262 {
263 dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
264 exec->codeBlock(),
265 exec,
266 static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
267 exec->vm().interpreter->getOpcodeID(pc[0].u.opcode),
268 exec->returnPC().value());
269 LLINT_END_IMPL();
270 }
271
272 #if ENABLE(JIT)
273 inline bool shouldJIT(ExecState* exec)
274 {
275 // You can modify this to turn off JITting without rebuilding the world.
276 return exec->vm().canUseJIT();
277 }
278
279 // Returns true if we should try to OSR.
280 inline bool jitCompileAndSetHeuristics(CodeBlock* codeBlock, ExecState* exec)
281 {
282 codeBlock->updateAllValueProfilePredictions();
283
284 if (!codeBlock->checkIfJITThresholdReached()) {
285 #if ENABLE(JIT_VERBOSE_OSR)
286 dataLogF(" JIT threshold should be lifted.\n");
287 #endif
288 return false;
289 }
290
291 CodeBlock::JITCompilationResult result = codeBlock->jitCompile(exec);
292 switch (result) {
293 case CodeBlock::AlreadyCompiled:
294 #if ENABLE(JIT_VERBOSE_OSR)
295 dataLogF(" Code was already compiled.\n");
296 #endif
297 codeBlock->jitSoon();
298 return true;
299 case CodeBlock::CouldNotCompile:
300 #if ENABLE(JIT_VERBOSE_OSR)
301 dataLogF(" JIT compilation failed.\n");
302 #endif
303 codeBlock->dontJITAnytimeSoon();
304 return false;
305 case CodeBlock::CompiledSuccessfully:
306 #if ENABLE(JIT_VERBOSE_OSR)
307 dataLogF(" JIT compilation successful.\n");
308 #endif
309 codeBlock->jitSoon();
310 return true;
311 }
312 RELEASE_ASSERT_NOT_REACHED();
313 return false;
314 }
315
316 enum EntryKind { Prologue, ArityCheck };
317 static SlowPathReturnType entryOSR(ExecState* exec, Instruction*, CodeBlock* codeBlock, const char *name, EntryKind kind)
318 {
319 #if ENABLE(JIT_VERBOSE_OSR)
320 dataLog(*codeBlock, ": Entered ", name, " with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
321 #else
322 UNUSED_PARAM(name);
323 #endif
324
325 if (!shouldJIT(exec)) {
326 codeBlock->dontJITAnytimeSoon();
327 LLINT_RETURN_TWO(0, exec);
328 }
329 if (!jitCompileAndSetHeuristics(codeBlock, exec))
330 LLINT_RETURN_TWO(0, exec);
331
332 if (kind == Prologue)
333 LLINT_RETURN_TWO(codeBlock->getJITCode().executableAddressAtOffset(0), exec);
334 ASSERT(kind == ArityCheck);
335 LLINT_RETURN_TWO(codeBlock->getJITCodeWithArityCheck().executableAddress(), exec);
336 }
337
338 LLINT_SLOW_PATH_DECL(entry_osr)
339 {
340 return entryOSR(exec, pc, exec->codeBlock(), "entry_osr", Prologue);
341 }
342
343 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call)
344 {
345 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call", Prologue);
346 }
347
348 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct)
349 {
350 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct", Prologue);
351 }
352
353 LLINT_SLOW_PATH_DECL(entry_osr_function_for_call_arityCheck)
354 {
355 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForCall), "entry_osr_function_for_call_arityCheck", ArityCheck);
356 }
357
358 LLINT_SLOW_PATH_DECL(entry_osr_function_for_construct_arityCheck)
359 {
360 return entryOSR(exec, pc, &jsCast<JSFunction*>(exec->callee())->jsExecutable()->generatedBytecodeFor(CodeForConstruct), "entry_osr_function_for_construct_arityCheck", ArityCheck);
361 }
362
363 LLINT_SLOW_PATH_DECL(loop_osr)
364 {
365 CodeBlock* codeBlock = exec->codeBlock();
366
367 #if ENABLE(JIT_VERBOSE_OSR)
368 dataLog(*codeBlock, ": Entered loop_osr with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
369 #endif
370
371 if (!shouldJIT(exec)) {
372 codeBlock->dontJITAnytimeSoon();
373 LLINT_RETURN_TWO(0, exec);
374 }
375
376 if (!jitCompileAndSetHeuristics(codeBlock, exec))
377 LLINT_RETURN_TWO(0, exec);
378
379 ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
380
381 Vector<BytecodeAndMachineOffset> map;
382 codeBlock->jitCodeMap()->decode(map);
383 BytecodeAndMachineOffset* mapping = binarySearch<BytecodeAndMachineOffset, unsigned>(map, map.size(), pc - codeBlock->instructions().begin(), BytecodeAndMachineOffset::getBytecodeIndex);
384 ASSERT(mapping);
385 ASSERT(mapping->m_bytecodeIndex == static_cast<unsigned>(pc - codeBlock->instructions().begin()));
386
387 void* jumpTarget = codeBlock->getJITCode().executableAddressAtOffset(mapping->m_machineCodeOffset);
388 ASSERT(jumpTarget);
389
390 LLINT_RETURN_TWO(jumpTarget, exec);
391 }
392
393 LLINT_SLOW_PATH_DECL(replace)
394 {
395 CodeBlock* codeBlock = exec->codeBlock();
396
397 #if ENABLE(JIT_VERBOSE_OSR)
398 dataLog(*codeBlock, ": Entered replace with executeCounter = ", codeBlock->llintExecuteCounter(), "\n");
399 #endif
400
401 if (shouldJIT(exec))
402 jitCompileAndSetHeuristics(codeBlock, exec);
403 else
404 codeBlock->dontJITAnytimeSoon();
405 LLINT_END_IMPL();
406 }
407 #endif // ENABLE(JIT)
408
409 LLINT_SLOW_PATH_DECL(stack_check)
410 {
411 LLINT_BEGIN();
412 #if LLINT_SLOW_PATH_TRACING
413 dataLogF("Checking stack height with exec = %p.\n", exec);
414 dataLogF("CodeBlock = %p.\n", exec->codeBlock());
415 dataLogF("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters);
416 dataLogF("Num vars = %u.\n", exec->codeBlock()->m_numVars);
417 dataLogF("Current end is at %p.\n", exec->vm().interpreter->stack().end());
418 #endif
419 ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->vm().interpreter->stack().end());
420 if (UNLIKELY(!vm.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) {
421 ReturnAddressPtr returnPC = exec->returnPC();
422 exec = exec->callerFrame();
423 vm.exception = createStackOverflowError(exec);
424 interpreterThrowInCaller(exec, returnPC);
425 pc = returnToThrowForThrownException(exec);
426 }
427 LLINT_END_IMPL();
428 }
429
430 LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck)
431 {
432 LLINT_BEGIN();
433 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForCall);
434 if (!newExec) {
435 ReturnAddressPtr returnPC = exec->returnPC();
436 exec = exec->callerFrame();
437 vm.exception = createStackOverflowError(exec);
438 interpreterThrowInCaller(exec, returnPC);
439 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
440 }
441 LLINT_RETURN_TWO(0, newExec);
442 }
443
444 LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck)
445 {
446 LLINT_BEGIN();
447 ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &vm.interpreter->stack(), CodeForConstruct);
448 if (!newExec) {
449 ReturnAddressPtr returnPC = exec->returnPC();
450 exec = exec->callerFrame();
451 vm.exception = createStackOverflowError(exec);
452 interpreterThrowInCaller(exec, returnPC);
453 LLINT_RETURN_TWO(bitwise_cast<void*>(static_cast<uintptr_t>(1)), exec);
454 }
455 LLINT_RETURN_TWO(0, newExec);
456 }
457
458 LLINT_SLOW_PATH_DECL(slow_path_create_activation)
459 {
460 LLINT_BEGIN();
461 #if LLINT_SLOW_PATH_TRACING
462 dataLogF("Creating an activation, exec = %p!\n", exec);
463 #endif
464 JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
465 exec->setScope(activation);
466 LLINT_RETURN(JSValue(activation));
467 }
468
469 LLINT_SLOW_PATH_DECL(slow_path_create_arguments)
470 {
471 LLINT_BEGIN();
472 JSValue arguments = JSValue(Arguments::create(vm, exec));
473 LLINT_CHECK_EXCEPTION();
474 exec->uncheckedR(pc[1].u.operand) = arguments;
475 exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)) = arguments;
476 LLINT_END();
477 }
478
479 LLINT_SLOW_PATH_DECL(slow_path_create_this)
480 {
481 LLINT_BEGIN();
482 JSFunction* constructor = jsCast<JSFunction*>(LLINT_OP(2).jsValue().asCell());
483
484 #if !ASSERT_DISABLED
485 ConstructData constructData;
486 ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
487 #endif
488
489 size_t inlineCapacity = pc[3].u.operand;
490 Structure* structure = constructor->allocationProfile(exec, inlineCapacity)->structure();
491 LLINT_RETURN(constructEmptyObject(exec, structure));
492 }
493
494 LLINT_SLOW_PATH_DECL(slow_path_convert_this)
495 {
496 LLINT_BEGIN();
497 JSValue v1 = LLINT_OP(1).jsValue();
498 ASSERT(v1.isPrimitive());
499 #if ENABLE(VALUE_PROFILER)
500 pc[OPCODE_LENGTH(op_convert_this) - 1].u.profile->m_buckets[0] =
501 JSValue::encode(v1.structureOrUndefined());
502 #endif
503 LLINT_RETURN(v1.toThisObject(exec));
504 }
505
506 LLINT_SLOW_PATH_DECL(slow_path_new_object)
507 {
508 LLINT_BEGIN();
509 LLINT_RETURN(constructEmptyObject(exec, pc[3].u.objectAllocationProfile->structure()));
510 }
511
512 LLINT_SLOW_PATH_DECL(slow_path_new_array)
513 {
514 LLINT_BEGIN();
515 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, bitwise_cast<JSValue*>(&LLINT_OP(2)), pc[3].u.operand));
516 }
517
518 LLINT_SLOW_PATH_DECL(slow_path_new_array_with_size)
519 {
520 LLINT_BEGIN();
521 LLINT_RETURN(constructArrayWithSizeQuirk(exec, pc[3].u.arrayAllocationProfile, exec->lexicalGlobalObject(), LLINT_OP_C(2).jsValue()));
522 }
523
524 LLINT_SLOW_PATH_DECL(slow_path_new_array_buffer)
525 {
526 LLINT_BEGIN();
527 LLINT_RETURN(constructArray(exec, pc[4].u.arrayAllocationProfile, exec->codeBlock()->constantBuffer(pc[2].u.operand), pc[3].u.operand));
528 }
529
530 LLINT_SLOW_PATH_DECL(slow_path_new_regexp)
531 {
532 LLINT_BEGIN();
533 RegExp* regExp = exec->codeBlock()->regexp(pc[2].u.operand);
534 if (!regExp->isValid())
535 LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
536 LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp));
537 }
538
539 LLINT_SLOW_PATH_DECL(slow_path_not)
540 {
541 LLINT_BEGIN();
542 LLINT_RETURN(jsBoolean(!LLINT_OP_C(2).jsValue().toBoolean(exec)));
543 }
544
545 LLINT_SLOW_PATH_DECL(slow_path_eq)
546 {
547 LLINT_BEGIN();
548 LLINT_RETURN(jsBoolean(JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
549 }
550
551 LLINT_SLOW_PATH_DECL(slow_path_neq)
552 {
553 LLINT_BEGIN();
554 LLINT_RETURN(jsBoolean(!JSValue::equal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
555 }
556
557 LLINT_SLOW_PATH_DECL(slow_path_stricteq)
558 {
559 LLINT_BEGIN();
560 LLINT_RETURN(jsBoolean(JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
561 }
562
563 LLINT_SLOW_PATH_DECL(slow_path_nstricteq)
564 {
565 LLINT_BEGIN();
566 LLINT_RETURN(jsBoolean(!JSValue::strictEqual(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
567 }
568
569 LLINT_SLOW_PATH_DECL(slow_path_less)
570 {
571 LLINT_BEGIN();
572 LLINT_RETURN(jsBoolean(jsLess<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
573 }
574
575 LLINT_SLOW_PATH_DECL(slow_path_lesseq)
576 {
577 LLINT_BEGIN();
578 LLINT_RETURN(jsBoolean(jsLessEq<true>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
579 }
580
581 LLINT_SLOW_PATH_DECL(slow_path_greater)
582 {
583 LLINT_BEGIN();
584 LLINT_RETURN(jsBoolean(jsLess<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
585 }
586
587 LLINT_SLOW_PATH_DECL(slow_path_greatereq)
588 {
589 LLINT_BEGIN();
590 LLINT_RETURN(jsBoolean(jsLessEq<false>(exec, LLINT_OP_C(3).jsValue(), LLINT_OP_C(2).jsValue())));
591 }
592
593 LLINT_SLOW_PATH_DECL(slow_path_pre_inc)
594 {
595 LLINT_BEGIN();
596 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) + 1));
597 }
598
599 LLINT_SLOW_PATH_DECL(slow_path_pre_dec)
600 {
601 LLINT_BEGIN();
602 LLINT_RETURN(jsNumber(LLINT_OP(1).jsValue().toNumber(exec) - 1));
603 }
604
605 LLINT_SLOW_PATH_DECL(slow_path_to_number)
606 {
607 LLINT_BEGIN();
608 LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toNumber(exec)));
609 }
610
611 LLINT_SLOW_PATH_DECL(slow_path_negate)
612 {
613 LLINT_BEGIN();
614 LLINT_RETURN(jsNumber(-LLINT_OP_C(2).jsValue().toNumber(exec)));
615 }
616
617 LLINT_SLOW_PATH_DECL(slow_path_add)
618 {
619 LLINT_BEGIN();
620 JSValue v1 = LLINT_OP_C(2).jsValue();
621 JSValue v2 = LLINT_OP_C(3).jsValue();
622
623 #if LLINT_SLOW_PATH_TRACING
624 dataLog("Trying to add ", v1, " to ", v2, ".\n");
625 #endif
626
627 if (v1.isString() && !v2.isObject())
628 LLINT_RETURN(jsString(exec, asString(v1), v2.toString(exec)));
629
630 if (v1.isNumber() && v2.isNumber())
631 LLINT_RETURN(jsNumber(v1.asNumber() + v2.asNumber()));
632
633 LLINT_RETURN(jsAddSlowCase(exec, v1, v2));
634 }
635
636 // The following arithmetic and bitwise operations need to be sure to run
637 // toNumber() on their operands in order. (A call to toNumber() is idempotent
638 // if an exception is already set on the ExecState.)
639
640 LLINT_SLOW_PATH_DECL(slow_path_mul)
641 {
642 LLINT_BEGIN();
643 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
644 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
645 LLINT_RETURN(jsNumber(a * b));
646 }
647
648 LLINT_SLOW_PATH_DECL(slow_path_sub)
649 {
650 LLINT_BEGIN();
651 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
652 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
653 LLINT_RETURN(jsNumber(a - b));
654 }
655
656 LLINT_SLOW_PATH_DECL(slow_path_div)
657 {
658 LLINT_BEGIN();
659 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
660 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
661 LLINT_RETURN(jsNumber(a / b));
662 }
663
664 LLINT_SLOW_PATH_DECL(slow_path_mod)
665 {
666 LLINT_BEGIN();
667 double a = LLINT_OP_C(2).jsValue().toNumber(exec);
668 double b = LLINT_OP_C(3).jsValue().toNumber(exec);
669 LLINT_RETURN(jsNumber(fmod(a, b)));
670 }
671
672 LLINT_SLOW_PATH_DECL(slow_path_lshift)
673 {
674 LLINT_BEGIN();
675 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
676 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
677 LLINT_RETURN(jsNumber(a << (b & 31)));
678 }
679
680 LLINT_SLOW_PATH_DECL(slow_path_rshift)
681 {
682 LLINT_BEGIN();
683 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
684 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
685 LLINT_RETURN(jsNumber(a >> (b & 31)));
686 }
687
688 LLINT_SLOW_PATH_DECL(slow_path_urshift)
689 {
690 LLINT_BEGIN();
691 uint32_t a = LLINT_OP_C(2).jsValue().toUInt32(exec);
692 uint32_t b = LLINT_OP_C(3).jsValue().toUInt32(exec);
693 LLINT_RETURN(jsNumber(a >> (b & 31)));
694 }
695
696 LLINT_SLOW_PATH_DECL(slow_path_bitand)
697 {
698 LLINT_BEGIN();
699 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
700 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
701 LLINT_RETURN(jsNumber(a & b));
702 }
703
704 LLINT_SLOW_PATH_DECL(slow_path_bitor)
705 {
706 LLINT_BEGIN();
707 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
708 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
709 LLINT_RETURN(jsNumber(a | b));
710 }
711
712 LLINT_SLOW_PATH_DECL(slow_path_bitxor)
713 {
714 LLINT_BEGIN();
715 int32_t a = LLINT_OP_C(2).jsValue().toInt32(exec);
716 int32_t b = LLINT_OP_C(3).jsValue().toInt32(exec);
717 LLINT_RETURN(jsNumber(a ^ b));
718 }
719
720 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
721 {
722 LLINT_BEGIN();
723
724 JSValue value = LLINT_OP_C(2).jsValue();
725 JSValue baseVal = LLINT_OP_C(3).jsValue();
726 if (baseVal.isObject()) {
727 JSObject* baseObject = asObject(baseVal);
728 ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
729 if (baseObject->structure()->typeInfo().implementsHasInstance()) {
730 pc += pc[4].u.operand;
731 LLINT_RETURN(jsBoolean(baseObject->methodTable()->customHasInstance(baseObject, exec, value)));
732 }
733 }
734 LLINT_THROW(createInvalidParamError(exec, "instanceof", baseVal));
735 }
736
737 LLINT_SLOW_PATH_DECL(slow_path_instanceof)
738 {
739 LLINT_BEGIN();
740 JSValue value = LLINT_OP_C(2).jsValue();
741 JSValue proto = LLINT_OP_C(3).jsValue();
742 ASSERT(!value.isObject() || !proto.isObject());
743 LLINT_RETURN(jsBoolean(JSObject::defaultHasInstance(exec, value, proto)));
744 }
745
746 LLINT_SLOW_PATH_DECL(slow_path_typeof)
747 {
748 LLINT_BEGIN();
749 LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
750 }
751
752 LLINT_SLOW_PATH_DECL(slow_path_is_object)
753 {
754 LLINT_BEGIN();
755 LLINT_RETURN(jsBoolean(jsIsObjectType(exec, LLINT_OP_C(2).jsValue())));
756 }
757
758 LLINT_SLOW_PATH_DECL(slow_path_is_function)
759 {
760 LLINT_BEGIN();
761 LLINT_RETURN(jsBoolean(jsIsFunctionType(LLINT_OP_C(2).jsValue())));
762 }
763
764 LLINT_SLOW_PATH_DECL(slow_path_in)
765 {
766 LLINT_BEGIN();
767 LLINT_RETURN(jsBoolean(CommonSlowPaths::opIn(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue())));
768 }
769
770 LLINT_SLOW_PATH_DECL(slow_path_resolve)
771 {
772 LLINT_BEGIN();
773 Identifier ident = exec->codeBlock()->identifier(pc[2].u.operand);
774 ResolveOperations* operations = pc[3].u.resolveOperations;
775 JSValue result = JSScope::resolve(exec, ident, operations);
776 ASSERT(operations->size());
777 if (operations->isEmpty())
778 LLINT_RETURN_PROFILED(op_resolve, result);
779
780 switch (operations->data()[0].m_operation) {
781 case ResolveOperation::GetAndReturnGlobalProperty:
782 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_property);
783 break;
784
785 case ResolveOperation::GetAndReturnGlobalVar:
786 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_global_var);
787 break;
788
789 case ResolveOperation::SkipTopScopeNode:
790 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_with_top_scope_check);
791 break;
792
793 case ResolveOperation::SkipScopes:
794 if (operations->data()[0].m_scopesToSkip)
795 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var);
796 else
797 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_scoped_var_on_top_scope);
798 break;
799
800 default:
801 break;
802 }
803 LLINT_RETURN_PROFILED(op_resolve, result);
804 }
805
806 LLINT_SLOW_PATH_DECL(slow_path_put_to_base)
807 {
808 LLINT_BEGIN();
809 PutToBaseOperation* operation = pc[4].u.putToBaseOperation;
810 JSScope::resolvePut(exec, LLINT_OP_C(1).jsValue(), exec->codeBlock()->identifier(pc[2].u.operand), LLINT_OP_C(3).jsValue(), operation);
811 switch (operation->m_kind) {
812 case PutToBaseOperation::VariablePut:
813 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_to_base_variable);
814 break;
815
816 default:
817 break;
818 }
819 LLINT_END();
820 }
821
822 LLINT_SLOW_PATH_DECL(slow_path_resolve_base)
823 {
824 LLINT_BEGIN();
825 Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
826 ResolveOperations* operations = pc[4].u.resolveOperations;
827 JSValue result;
828 if (pc[3].u.operand) {
829 result = JSScope::resolveBase(exec, ident, true, operations, pc[5].u.putToBaseOperation);
830 if (!result)
831 LLINT_THROW(vm.exception);
832 } else
833 result = JSScope::resolveBase(exec, ident, false, operations, pc[5].u.putToBaseOperation);
834
835 ASSERT(operations->size());
836 if (operations->isEmpty()) {
837 LLINT_PROFILE_VALUE(op_resolve_base, result);
838 LLINT_RETURN(result);
839 }
840
841 switch (operations->data()[0].m_operation) {
842 case ResolveOperation::ReturnGlobalObjectAsBase:
843 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_global);
844 break;
845
846 case ResolveOperation::SkipTopScopeNode:
847 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope_with_top_scope_check);
848 break;
849
850 case ResolveOperation::SkipScopes:
851 pc[0].u.opcode = LLInt::getOpcode(llint_op_resolve_base_to_scope);
852 break;
853
854 default:
855 break;
856 }
857 LLINT_PROFILE_VALUE(op_resolve_base, result);
858 LLINT_RETURN(result);
859 }
860
861 LLINT_SLOW_PATH_DECL(slow_path_resolve_with_base)
862 {
863 LLINT_BEGIN();
864 ResolveOperations* operations = pc[4].u.resolveOperations;
865 JSValue result = JSScope::resolveWithBase(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations, pc[5].u.putToBaseOperation);
866 LLINT_CHECK_EXCEPTION();
867 LLINT_OP(2) = result;
868 LLINT_PROFILE_VALUE(op_resolve_with_base, result);
869 LLINT_END();
870 }
871
872 LLINT_SLOW_PATH_DECL(slow_path_resolve_with_this)
873 {
874 LLINT_BEGIN();
875 ResolveOperations* operations = pc[4].u.resolveOperations;
876 JSValue result = JSScope::resolveWithThis(exec, exec->codeBlock()->identifier(pc[3].u.operand), &LLINT_OP(1), operations);
877 LLINT_CHECK_EXCEPTION();
878 LLINT_OP(2) = result;
879 LLINT_PROFILE_VALUE(op_resolve_with_this, result);
880 LLINT_END();
881 }
882
883 LLINT_SLOW_PATH_DECL(slow_path_init_global_const_check)
884 {
885 LLINT_BEGIN();
886 CodeBlock* codeBlock = exec->codeBlock();
887 symbolTablePut(codeBlock->globalObject(), exec, codeBlock->identifier(pc[4].u.operand), LLINT_OP_C(2).jsValue(), true);
888 LLINT_END();
889 }
890
891 LLINT_SLOW_PATH_DECL(slow_path_get_by_id)
892 {
893 LLINT_BEGIN();
894 CodeBlock* codeBlock = exec->codeBlock();
895 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
896 JSValue baseValue = LLINT_OP_C(2).jsValue();
897 PropertySlot slot(baseValue);
898
899 JSValue result = baseValue.get(exec, ident, slot);
900 LLINT_CHECK_EXCEPTION();
901 LLINT_OP(1) = result;
902
903 if (!LLINT_ALWAYS_ACCESS_SLOW
904 && baseValue.isCell()
905 && slot.isCacheable()
906 && slot.slotBase() == baseValue
907 && slot.cachedPropertyType() == PropertySlot::Value) {
908
909 JSCell* baseCell = baseValue.asCell();
910 Structure* structure = baseCell->structure();
911
912 if (!structure->isUncacheableDictionary()
913 && !structure->typeInfo().prohibitsPropertyCaching()) {
914 pc[4].u.structure.set(
915 vm, codeBlock->ownerExecutable(), structure);
916 if (isInlineOffset(slot.cachedOffset())) {
917 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id);
918 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
919 } else {
920 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_by_id_out_of_line);
921 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
922 }
923 }
924 }
925
926 if (!LLINT_ALWAYS_ACCESS_SLOW
927 && isJSArray(baseValue)
928 && ident == exec->propertyNames().length) {
929 pc[0].u.opcode = LLInt::getOpcode(llint_op_get_array_length);
930 #if ENABLE(VALUE_PROFILER)
931 ArrayProfile* arrayProfile = codeBlock->getOrAddArrayProfile(pc - codeBlock->instructions().begin());
932 arrayProfile->observeStructure(baseValue.asCell()->structure());
933 pc[4].u.arrayProfile = arrayProfile;
934 #endif
935 }
936
937 #if ENABLE(VALUE_PROFILER)
938 pc[OPCODE_LENGTH(op_get_by_id) - 1].u.profile->m_buckets[0] = JSValue::encode(result);
939 #endif
940 LLINT_END();
941 }
942
943 LLINT_SLOW_PATH_DECL(slow_path_get_arguments_length)
944 {
945 LLINT_BEGIN();
946 CodeBlock* codeBlock = exec->codeBlock();
947 Identifier& ident = codeBlock->identifier(pc[3].u.operand);
948 JSValue baseValue = LLINT_OP(2).jsValue();
949 PropertySlot slot(baseValue);
950 LLINT_RETURN(baseValue.get(exec, ident, slot));
951 }
952
953 LLINT_SLOW_PATH_DECL(slow_path_put_by_id)
954 {
955 LLINT_BEGIN();
956 CodeBlock* codeBlock = exec->codeBlock();
957 Identifier& ident = codeBlock->identifier(pc[2].u.operand);
958
959 JSValue baseValue = LLINT_OP_C(1).jsValue();
960 PutPropertySlot slot(codeBlock->isStrictMode());
961 if (pc[8].u.operand)
962 asObject(baseValue)->putDirect(vm, ident, LLINT_OP_C(3).jsValue(), slot);
963 else
964 baseValue.put(exec, ident, LLINT_OP_C(3).jsValue(), slot);
965 LLINT_CHECK_EXCEPTION();
966
967 if (!LLINT_ALWAYS_ACCESS_SLOW
968 && baseValue.isCell()
969 && slot.isCacheable()) {
970
971 JSCell* baseCell = baseValue.asCell();
972 Structure* structure = baseCell->structure();
973
974 if (!structure->isUncacheableDictionary()
975 && !structure->typeInfo().prohibitsPropertyCaching()
976 && baseCell == slot.base()) {
977
978 if (slot.type() == PutPropertySlot::NewProperty) {
979 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) {
980 ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
981
982 // This is needed because some of the methods we call
983 // below may GC.
984 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
985
986 if (normalizePrototypeChain(exec, baseCell) != InvalidPrototypeChain) {
987 ASSERT(structure->previousID()->isObject());
988 pc[4].u.structure.set(
989 vm, codeBlock->ownerExecutable(), structure->previousID());
990 if (isInlineOffset(slot.cachedOffset()))
991 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
992 else
993 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
994 pc[6].u.structure.set(
995 vm, codeBlock->ownerExecutable(), structure);
996 StructureChain* chain = structure->prototypeChain(exec);
997 ASSERT(chain);
998 pc[7].u.structureChain.set(
999 vm, codeBlock->ownerExecutable(), chain);
1000
1001 if (pc[8].u.operand) {
1002 if (isInlineOffset(slot.cachedOffset()))
1003 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct);
1004 else
1005 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_direct_out_of_line);
1006 } else {
1007 if (isInlineOffset(slot.cachedOffset()))
1008 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal);
1009 else
1010 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_transition_normal_out_of_line);
1011 }
1012 }
1013 }
1014 } else {
1015 pc[4].u.structure.set(
1016 vm, codeBlock->ownerExecutable(), structure);
1017 if (isInlineOffset(slot.cachedOffset())) {
1018 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id);
1019 pc[5].u.operand = offsetInInlineStorage(slot.cachedOffset()) * sizeof(JSValue) + JSObject::offsetOfInlineStorage();
1020 } else {
1021 pc[0].u.opcode = LLInt::getOpcode(llint_op_put_by_id_out_of_line);
1022 pc[5].u.operand = offsetInButterfly(slot.cachedOffset()) * sizeof(JSValue);
1023 }
1024 }
1025 }
1026 }
1027
1028 LLINT_END();
1029 }
1030
1031 LLINT_SLOW_PATH_DECL(slow_path_del_by_id)
1032 {
1033 LLINT_BEGIN();
1034 CodeBlock* codeBlock = exec->codeBlock();
1035 JSObject* baseObject = LLINT_OP_C(2).jsValue().toObject(exec);
1036 bool couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, codeBlock->identifier(pc[3].u.operand));
1037 LLINT_CHECK_EXCEPTION();
1038 if (!couldDelete && codeBlock->isStrictMode())
1039 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1040 LLINT_RETURN(jsBoolean(couldDelete));
1041 }
1042
1043 inline JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript)
1044 {
1045 if (LIKELY(baseValue.isCell() && subscript.isString())) {
1046 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(exec, asString(subscript)->value(exec)))
1047 return result;
1048 }
1049
1050 if (subscript.isUInt32()) {
1051 uint32_t i = subscript.asUInt32();
1052 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1053 return asString(baseValue)->getIndex(exec, i);
1054
1055 return baseValue.get(exec, i);
1056 }
1057
1058 if (isName(subscript))
1059 return baseValue.get(exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
1060
1061 Identifier property(exec, subscript.toString(exec)->value(exec));
1062 return baseValue.get(exec, property);
1063 }
1064
1065 LLINT_SLOW_PATH_DECL(slow_path_get_by_val)
1066 {
1067 LLINT_BEGIN();
1068 LLINT_RETURN_PROFILED(op_get_by_val, getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
1069 }
1070
1071 LLINT_SLOW_PATH_DECL(slow_path_get_argument_by_val)
1072 {
1073 LLINT_BEGIN();
1074 JSValue arguments = LLINT_OP(2).jsValue();
1075 if (!arguments) {
1076 arguments = Arguments::create(vm, exec);
1077 LLINT_CHECK_EXCEPTION();
1078 LLINT_OP(2) = arguments;
1079 exec->uncheckedR(unmodifiedArgumentsRegister(pc[2].u.operand)) = arguments;
1080 }
1081
1082 LLINT_RETURN_PROFILED(op_get_argument_by_val, getByVal(exec, arguments, LLINT_OP_C(3).jsValue()));
1083 }
1084
1085 LLINT_SLOW_PATH_DECL(slow_path_get_by_pname)
1086 {
1087 LLINT_BEGIN();
1088 LLINT_RETURN(getByVal(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue()));
1089 }
1090
1091 LLINT_SLOW_PATH_DECL(slow_path_put_by_val)
1092 {
1093 LLINT_BEGIN();
1094
1095 JSValue baseValue = LLINT_OP_C(1).jsValue();
1096 JSValue subscript = LLINT_OP_C(2).jsValue();
1097 JSValue value = LLINT_OP_C(3).jsValue();
1098
1099 if (LIKELY(subscript.isUInt32())) {
1100 uint32_t i = subscript.asUInt32();
1101 if (baseValue.isObject()) {
1102 JSObject* object = asObject(baseValue);
1103 if (object->canSetIndexQuickly(i))
1104 object->setIndexQuickly(vm, i, value);
1105 else
1106 object->methodTable()->putByIndex(object, exec, i, value, exec->codeBlock()->isStrictMode());
1107 LLINT_END();
1108 }
1109 baseValue.putByIndex(exec, i, value, exec->codeBlock()->isStrictMode());
1110 LLINT_END();
1111 }
1112
1113 if (isName(subscript)) {
1114 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1115 baseValue.put(exec, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
1116 LLINT_END();
1117 }
1118
1119 Identifier property(exec, subscript.toString(exec)->value(exec));
1120 LLINT_CHECK_EXCEPTION();
1121 PutPropertySlot slot(exec->codeBlock()->isStrictMode());
1122 baseValue.put(exec, property, value, slot);
1123 LLINT_END();
1124 }
1125
1126 LLINT_SLOW_PATH_DECL(slow_path_del_by_val)
1127 {
1128 LLINT_BEGIN();
1129 JSValue baseValue = LLINT_OP_C(2).jsValue();
1130 JSObject* baseObject = baseValue.toObject(exec);
1131
1132 JSValue subscript = LLINT_OP_C(3).jsValue();
1133
1134 bool couldDelete;
1135
1136 uint32_t i;
1137 if (subscript.getUInt32(i))
1138 couldDelete = baseObject->methodTable()->deletePropertyByIndex(baseObject, exec, i);
1139 else if (isName(subscript))
1140 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, jsCast<NameInstance*>(subscript.asCell())->privateName());
1141 else {
1142 LLINT_CHECK_EXCEPTION();
1143 Identifier property(exec, subscript.toString(exec)->value(exec));
1144 LLINT_CHECK_EXCEPTION();
1145 couldDelete = baseObject->methodTable()->deleteProperty(baseObject, exec, property);
1146 }
1147
1148 if (!couldDelete && exec->codeBlock()->isStrictMode())
1149 LLINT_THROW(createTypeError(exec, "Unable to delete property."));
1150
1151 LLINT_RETURN(jsBoolean(couldDelete));
1152 }
1153
1154 LLINT_SLOW_PATH_DECL(slow_path_put_by_index)
1155 {
1156 LLINT_BEGIN();
1157 JSValue arrayValue = LLINT_OP_C(1).jsValue();
1158 ASSERT(isJSArray(arrayValue));
1159 asArray(arrayValue)->putDirectIndex(exec, pc[2].u.operand, LLINT_OP_C(3).jsValue());
1160 LLINT_END();
1161 }
1162
1163 LLINT_SLOW_PATH_DECL(slow_path_put_getter_setter)
1164 {
1165 LLINT_BEGIN();
1166 ASSERT(LLINT_OP(1).jsValue().isObject());
1167 JSObject* baseObj = asObject(LLINT_OP(1).jsValue());
1168
1169 GetterSetter* accessor = GetterSetter::create(exec);
1170 LLINT_CHECK_EXCEPTION();
1171
1172 JSValue getter = LLINT_OP(3).jsValue();
1173 JSValue setter = LLINT_OP(4).jsValue();
1174 ASSERT(getter.isObject() || getter.isUndefined());
1175 ASSERT(setter.isObject() || setter.isUndefined());
1176 ASSERT(getter.isObject() || setter.isObject());
1177
1178 if (!getter.isUndefined())
1179 accessor->setGetter(vm, asObject(getter));
1180 if (!setter.isUndefined())
1181 accessor->setSetter(vm, asObject(setter));
1182 baseObj->putDirectAccessor(
1183 exec,
1184 exec->codeBlock()->identifier(pc[2].u.operand),
1185 accessor, Accessor);
1186 LLINT_END();
1187 }
1188
1189 LLINT_SLOW_PATH_DECL(slow_path_jtrue)
1190 {
1191 LLINT_BEGIN();
1192 LLINT_BRANCH(op_jtrue, LLINT_OP_C(1).jsValue().toBoolean(exec));
1193 }
1194
1195 LLINT_SLOW_PATH_DECL(slow_path_jfalse)
1196 {
1197 LLINT_BEGIN();
1198 LLINT_BRANCH(op_jfalse, !LLINT_OP_C(1).jsValue().toBoolean(exec));
1199 }
1200
1201 LLINT_SLOW_PATH_DECL(slow_path_jless)
1202 {
1203 LLINT_BEGIN();
1204 LLINT_BRANCH(op_jless, jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1205 }
1206
1207 LLINT_SLOW_PATH_DECL(slow_path_jnless)
1208 {
1209 LLINT_BEGIN();
1210 LLINT_BRANCH(op_jnless, !jsLess<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1211 }
1212
1213 LLINT_SLOW_PATH_DECL(slow_path_jgreater)
1214 {
1215 LLINT_BEGIN();
1216 LLINT_BRANCH(op_jgreater, jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1217 }
1218
1219 LLINT_SLOW_PATH_DECL(slow_path_jngreater)
1220 {
1221 LLINT_BEGIN();
1222 LLINT_BRANCH(op_jngreater, !jsLess<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1223 }
1224
1225 LLINT_SLOW_PATH_DECL(slow_path_jlesseq)
1226 {
1227 LLINT_BEGIN();
1228 LLINT_BRANCH(op_jlesseq, jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1229 }
1230
1231 LLINT_SLOW_PATH_DECL(slow_path_jnlesseq)
1232 {
1233 LLINT_BEGIN();
1234 LLINT_BRANCH(op_jnlesseq, !jsLessEq<true>(exec, LLINT_OP_C(1).jsValue(), LLINT_OP_C(2).jsValue()));
1235 }
1236
1237 LLINT_SLOW_PATH_DECL(slow_path_jgreatereq)
1238 {
1239 LLINT_BEGIN();
1240 LLINT_BRANCH(op_jgreatereq, jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1241 }
1242
1243 LLINT_SLOW_PATH_DECL(slow_path_jngreatereq)
1244 {
1245 LLINT_BEGIN();
1246 LLINT_BRANCH(op_jngreatereq, !jsLessEq<false>(exec, LLINT_OP_C(2).jsValue(), LLINT_OP_C(1).jsValue()));
1247 }
1248
1249 LLINT_SLOW_PATH_DECL(slow_path_switch_imm)
1250 {
1251 LLINT_BEGIN();
1252 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1253 ASSERT(scrutinee.isDouble());
1254 double value = scrutinee.asDouble();
1255 int32_t intValue = static_cast<int32_t>(value);
1256 int defaultOffset = pc[2].u.operand;
1257 if (value == intValue) {
1258 CodeBlock* codeBlock = exec->codeBlock();
1259 pc += codeBlock->immediateSwitchJumpTable(pc[1].u.operand).offsetForValue(intValue, defaultOffset);
1260 } else
1261 pc += defaultOffset;
1262 LLINT_END();
1263 }
1264
1265 LLINT_SLOW_PATH_DECL(slow_path_switch_char)
1266 {
1267 LLINT_BEGIN();
1268 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1269 ASSERT(scrutinee.isString());
1270 JSString* string = asString(scrutinee);
1271 ASSERT(string->length() == 1);
1272 int defaultOffset = pc[2].u.operand;
1273 StringImpl* impl = string->value(exec).impl();
1274 CodeBlock* codeBlock = exec->codeBlock();
1275 pc += codeBlock->characterSwitchJumpTable(pc[1].u.operand).offsetForValue((*impl)[0], defaultOffset);
1276 LLINT_END();
1277 }
1278
1279 LLINT_SLOW_PATH_DECL(slow_path_switch_string)
1280 {
1281 LLINT_BEGIN();
1282 JSValue scrutinee = LLINT_OP_C(3).jsValue();
1283 int defaultOffset = pc[2].u.operand;
1284 if (!scrutinee.isString())
1285 pc += defaultOffset;
1286 else {
1287 CodeBlock* codeBlock = exec->codeBlock();
1288 pc += codeBlock->stringSwitchJumpTable(pc[1].u.operand).offsetForValue(asString(scrutinee)->value(exec).impl(), defaultOffset);
1289 }
1290 LLINT_END();
1291 }
1292
1293 LLINT_SLOW_PATH_DECL(slow_path_new_func)
1294 {
1295 LLINT_BEGIN();
1296 CodeBlock* codeBlock = exec->codeBlock();
1297 ASSERT(codeBlock->codeType() != FunctionCode
1298 || !codeBlock->needsFullScopeChain()
1299 || exec->uncheckedR(codeBlock->activationRegister()).jsValue());
1300 #if LLINT_SLOW_PATH_TRACING
1301 dataLogF("Creating function!\n");
1302 #endif
1303 LLINT_RETURN(JSFunction::create(exec, codeBlock->functionDecl(pc[2].u.operand), exec->scope()));
1304 }
1305
1306 LLINT_SLOW_PATH_DECL(slow_path_new_func_exp)
1307 {
1308 LLINT_BEGIN();
1309 CodeBlock* codeBlock = exec->codeBlock();
1310 FunctionExecutable* function = codeBlock->functionExpr(pc[2].u.operand);
1311 JSFunction* func = JSFunction::create(exec, function, exec->scope());
1312
1313 LLINT_RETURN(func);
1314 }
1315
1316 static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, JSValue callee, CodeSpecializationKind kind)
1317 {
1318 #if LLINT_SLOW_PATH_TRACING
1319 dataLog("Performing host call.\n");
1320 #endif
1321
1322 ExecState* exec = execCallee->callerFrame();
1323 VM& vm = exec->vm();
1324
1325 execCallee->setScope(exec->scope());
1326 execCallee->setCodeBlock(0);
1327 execCallee->clearReturnPC();
1328
1329 if (kind == CodeForCall) {
1330 CallData callData;
1331 CallType callType = getCallData(callee, callData);
1332
1333 ASSERT(callType != CallTypeJS);
1334
1335 if (callType == CallTypeHost) {
1336 NativeCallFrameTracer tracer(&vm, execCallee);
1337 execCallee->setCallee(asObject(callee));
1338 vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1339
1340 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1341 }
1342
1343 #if LLINT_SLOW_PATH_TRACING
1344 dataLog("Call callee is not a function: ", callee, "\n");
1345 #endif
1346
1347 ASSERT(callType == CallTypeNone);
1348 LLINT_CALL_THROW(exec, pc, createNotAFunctionError(exec, callee));
1349 }
1350
1351 ASSERT(kind == CodeForConstruct);
1352
1353 ConstructData constructData;
1354 ConstructType constructType = getConstructData(callee, constructData);
1355
1356 ASSERT(constructType != ConstructTypeJS);
1357
1358 if (constructType == ConstructTypeHost) {
1359 NativeCallFrameTracer tracer(&vm, execCallee);
1360 execCallee->setCallee(asObject(callee));
1361 vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1362
1363 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1364 }
1365
1366 #if LLINT_SLOW_PATH_TRACING
1367 dataLog("Constructor callee is not a function: ", callee, "\n");
1368 #endif
1369
1370 ASSERT(constructType == ConstructTypeNone);
1371 LLINT_CALL_THROW(exec, pc, createNotAConstructorError(exec, callee));
1372 }
1373
1374 inline SlowPathReturnType setUpCall(ExecState* execCallee, Instruction* pc, CodeSpecializationKind kind, JSValue calleeAsValue, LLIntCallLinkInfo* callLinkInfo = 0)
1375 {
1376 #if LLINT_SLOW_PATH_TRACING
1377 dataLogF("Performing call with recorded PC = %p\n", execCallee->callerFrame()->currentVPC());
1378 #endif
1379
1380 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1381 if (!calleeAsFunctionCell)
1382 return handleHostCall(execCallee, pc, calleeAsValue, kind);
1383
1384 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1385 JSScope* scope = callee->scopeUnchecked();
1386 VM& vm = *scope->vm();
1387 execCallee->setScope(scope);
1388 ExecutableBase* executable = callee->executable();
1389
1390 MacroAssemblerCodePtr codePtr;
1391 CodeBlock* codeBlock = 0;
1392 if (executable->isHostFunction())
1393 codePtr = executable->hostCodeEntryFor(kind);
1394 else {
1395 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1396 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1397 if (error)
1398 LLINT_CALL_THROW(execCallee->callerFrame(), pc, error);
1399 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1400 ASSERT(codeBlock);
1401 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1402 codePtr = functionExecutable->jsCodeWithArityCheckEntryFor(kind);
1403 else
1404 codePtr = functionExecutable->jsCodeEntryFor(kind);
1405 }
1406
1407 if (!LLINT_ALWAYS_ACCESS_SLOW && callLinkInfo) {
1408 if (callLinkInfo->isOnList())
1409 callLinkInfo->remove();
1410 ExecState* execCaller = execCallee->callerFrame();
1411 callLinkInfo->callee.set(vm, execCaller->codeBlock()->ownerExecutable(), callee);
1412 callLinkInfo->lastSeenCallee.set(vm, execCaller->codeBlock()->ownerExecutable(), callee);
1413 callLinkInfo->machineCodeTarget = codePtr;
1414 if (codeBlock)
1415 codeBlock->linkIncomingCall(callLinkInfo);
1416 }
1417
1418 LLINT_CALL_RETURN(execCallee, pc, codePtr.executableAddress());
1419 }
1420
1421 inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpecializationKind kind)
1422 {
1423 // This needs to:
1424 // - Set up a call frame.
1425 // - Figure out what to call and compile it if necessary.
1426 // - If possible, link the call's inline cache.
1427 // - Return a tuple of machine code address to call and the new call frame.
1428
1429 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1430
1431 ExecState* execCallee = exec + pc[3].u.operand;
1432
1433 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1434 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1435 execCallee->setCallerFrame(exec);
1436
1437 ASSERT(pc[4].u.callLinkInfo);
1438 return setUpCall(execCallee, pc, kind, calleeAsValue, pc[4].u.callLinkInfo);
1439 }
1440
1441 LLINT_SLOW_PATH_DECL(slow_path_call)
1442 {
1443 LLINT_BEGIN_NO_SET_PC();
1444 return genericCall(exec, pc, CodeForCall);
1445 }
1446
1447 LLINT_SLOW_PATH_DECL(slow_path_construct)
1448 {
1449 LLINT_BEGIN_NO_SET_PC();
1450 return genericCall(exec, pc, CodeForConstruct);
1451 }
1452
1453 LLINT_SLOW_PATH_DECL(slow_path_call_varargs)
1454 {
1455 LLINT_BEGIN();
1456 // This needs to:
1457 // - Set up a call frame while respecting the variable arguments.
1458 // - Figure out what to call and compile it if necessary.
1459 // - Return a tuple of machine code address to call and the new call frame.
1460
1461 JSValue calleeAsValue = LLINT_OP_C(1).jsValue();
1462
1463 ExecState* execCallee = loadVarargs(
1464 exec, &vm.interpreter->stack(),
1465 LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand);
1466 LLINT_CALL_CHECK_EXCEPTION(exec, pc);
1467
1468 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1469 execCallee->setCallerFrame(exec);
1470 exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs));
1471
1472 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1473 }
1474
1475 LLINT_SLOW_PATH_DECL(slow_path_call_eval)
1476 {
1477 LLINT_BEGIN_NO_SET_PC();
1478 JSValue calleeAsValue = LLINT_OP(1).jsValue();
1479
1480 ExecState* execCallee = exec + pc[3].u.operand;
1481
1482 execCallee->setArgumentCountIncludingThis(pc[2].u.operand);
1483 execCallee->setCallerFrame(exec);
1484 execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
1485 execCallee->setScope(exec->scope());
1486 execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
1487 execCallee->setCodeBlock(0);
1488 exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_eval));
1489
1490 if (!isHostFunction(calleeAsValue, globalFuncEval))
1491 return setUpCall(execCallee, pc, CodeForCall, calleeAsValue);
1492
1493 vm.hostCallReturnValue = eval(execCallee);
1494 LLINT_CALL_RETURN(execCallee, pc, LLInt::getCodePtr(getHostCallReturnValue));
1495 }
1496
1497 LLINT_SLOW_PATH_DECL(slow_path_tear_off_activation)
1498 {
1499 LLINT_BEGIN();
1500 ASSERT(exec->codeBlock()->needsFullScopeChain());
1501 jsCast<JSActivation*>(LLINT_OP(1).jsValue())->tearOff(vm);
1502 LLINT_END();
1503 }
1504
1505 LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
1506 {
1507 LLINT_BEGIN();
1508 ASSERT(exec->codeBlock()->usesArguments());
1509 Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
1510 if (JSValue activationValue = LLINT_OP_C(2).jsValue())
1511 arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
1512 else
1513 arguments->tearOff(exec);
1514 LLINT_END();
1515 }
1516
1517 LLINT_SLOW_PATH_DECL(slow_path_strcat)
1518 {
1519 LLINT_BEGIN();
1520 LLINT_RETURN(jsString(exec, &LLINT_OP(2), pc[3].u.operand));
1521 }
1522
1523 LLINT_SLOW_PATH_DECL(slow_path_to_primitive)
1524 {
1525 LLINT_BEGIN();
1526 LLINT_RETURN(LLINT_OP_C(2).jsValue().toPrimitive(exec));
1527 }
1528
1529 LLINT_SLOW_PATH_DECL(slow_path_get_pnames)
1530 {
1531 LLINT_BEGIN();
1532 JSValue v = LLINT_OP(2).jsValue();
1533 if (v.isUndefinedOrNull()) {
1534 pc += pc[5].u.operand;
1535 LLINT_END();
1536 }
1537
1538 JSObject* o = v.toObject(exec);
1539 Structure* structure = o->structure();
1540 JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1541 if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(exec))
1542 jsPropertyNameIterator = JSPropertyNameIterator::create(exec, o);
1543
1544 LLINT_OP(1) = JSValue(jsPropertyNameIterator);
1545 LLINT_OP(2) = JSValue(o);
1546 LLINT_OP(3) = Register::withInt(0);
1547 LLINT_OP(4) = Register::withInt(jsPropertyNameIterator->size());
1548
1549 pc += OPCODE_LENGTH(op_get_pnames);
1550 LLINT_END();
1551 }
1552
1553 LLINT_SLOW_PATH_DECL(slow_path_next_pname)
1554 {
1555 LLINT_BEGIN();
1556 JSObject* base = asObject(LLINT_OP(2).jsValue());
1557 JSString* property = asString(LLINT_OP(1).jsValue());
1558 if (base->hasProperty(exec, Identifier(exec, property->value(exec)))) {
1559 // Go to target.
1560 pc += pc[6].u.operand;
1561 } // Else, don't change the PC, so the interpreter will reloop.
1562 LLINT_END();
1563 }
1564
1565 LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
1566 {
1567 LLINT_BEGIN();
1568 JSValue v = LLINT_OP_C(1).jsValue();
1569 JSObject* o = v.toObject(exec);
1570 LLINT_CHECK_EXCEPTION();
1571
1572 exec->setScope(JSWithScope::create(exec, o));
1573
1574 LLINT_END();
1575 }
1576
1577 LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
1578 {
1579 LLINT_BEGIN();
1580 exec->setScope(exec->scope()->next());
1581 LLINT_END();
1582 }
1583
1584 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
1585 {
1586 LLINT_BEGIN();
1587 CodeBlock* codeBlock = exec->codeBlock();
1588 JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
1589 exec->setScope(scope);
1590 LLINT_END();
1591 }
1592
1593 LLINT_SLOW_PATH_DECL(slow_path_throw)
1594 {
1595 LLINT_BEGIN();
1596 LLINT_THROW(LLINT_OP_C(1).jsValue());
1597 }
1598
1599 LLINT_SLOW_PATH_DECL(slow_path_throw_static_error)
1600 {
1601 LLINT_BEGIN();
1602 if (pc[2].u.operand)
1603 LLINT_THROW(createReferenceError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1604 else
1605 LLINT_THROW(createTypeError(exec, LLINT_OP_C(1).jsValue().toString(exec)->value(exec)));
1606 }
1607
1608 LLINT_SLOW_PATH_DECL(slow_path_handle_watchdog_timer)
1609 {
1610 LLINT_BEGIN_NO_SET_PC();
1611 if (UNLIKELY(vm.watchdog.didFire(exec)))
1612 LLINT_THROW(createTerminatedExecutionException(&vm));
1613 LLINT_RETURN_TWO(0, exec);
1614 }
1615
1616 LLINT_SLOW_PATH_DECL(slow_path_debug)
1617 {
1618 LLINT_BEGIN();
1619 int debugHookID = pc[1].u.operand;
1620 int firstLine = pc[2].u.operand;
1621 int lastLine = pc[3].u.operand;
1622 int column = pc[4].u.operand;
1623
1624 vm.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
1625
1626 LLINT_END();
1627 }
1628
1629 LLINT_SLOW_PATH_DECL(slow_path_profile_will_call)
1630 {
1631 LLINT_BEGIN();
1632 if (LegacyProfiler* profiler = vm.enabledProfiler())
1633 profiler->willExecute(exec, LLINT_OP(1).jsValue());
1634 LLINT_END();
1635 }
1636
1637 LLINT_SLOW_PATH_DECL(slow_path_profile_did_call)
1638 {
1639 LLINT_BEGIN();
1640 if (LegacyProfiler* profiler = vm.enabledProfiler())
1641 profiler->didExecute(exec, LLINT_OP(1).jsValue());
1642 LLINT_END();
1643 }
1644
1645 LLINT_SLOW_PATH_DECL(throw_from_native_call)
1646 {
1647 LLINT_BEGIN();
1648 ASSERT(vm.exception);
1649 LLINT_END();
1650 }
1651
1652 } } // namespace JSC::LLInt
1653
1654 #endif // ENABLE(LLINT)