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