Varargs frame set-up should be factored out for use by other JITs
[WebKit-https.git] / Source / JavaScriptCore / interpreter / Interpreter.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "Interpreter.h"
32
33 #include "Arguments.h"
34 #include "BatchedTransitionOptimizer.h"
35 #include "CallFrameClosure.h"
36 #include "CallFrameInlines.h"
37 #include "CodeBlock.h"
38 #include "Heap.h"
39 #include "Debugger.h"
40 #include "DebuggerCallFrame.h"
41 #include "ErrorInstance.h"
42 #include "EvalCodeCache.h"
43 #include "ExceptionHelpers.h"
44 #include "GetterSetter.h"
45 #include "JSArray.h"
46 #include "JSBoundFunction.h"
47 #include "JSLexicalEnvironment.h"
48 #include "JSNameScope.h"
49 #include "JSNotAnObject.h"
50 #include "JSStackInlines.h"
51 #include "JSString.h"
52 #include "JSWithScope.h"
53 #include "LLIntCLoop.h"
54 #include "LLIntThunks.h"
55 #include "LegacyProfiler.h"
56 #include "LiteralParser.h"
57 #include "ObjectPrototype.h"
58 #include "JSCInlines.h"
59 #include "Parser.h"
60 #include "ProtoCallFrame.h"
61 #include "RegExpObject.h"
62 #include "RegExpPrototype.h"
63 #include "Register.h"
64 #include "SamplingTool.h"
65 #include "StackAlignment.h"
66 #include "StackVisitor.h"
67 #include "StrictEvalActivation.h"
68 #include "StrongInlines.h"
69 #include "Symbol.h"
70 #include "VMEntryScope.h"
71 #include "VirtualRegister.h"
72
73 #include <limits.h>
74 #include <stdio.h>
75 #include <wtf/StackStats.h>
76 #include <wtf/StdLibExtras.h>
77 #include <wtf/StringPrintStream.h>
78 #include <wtf/Threading.h>
79 #include <wtf/WTFThreadData.h>
80 #include <wtf/text/StringBuilder.h>
81
82 #if ENABLE(JIT)
83 #include "JIT.h"
84 #endif
85
86 using namespace std;
87
88 namespace JSC {
89
90 JSValue eval(CallFrame* callFrame)
91 {
92     if (!callFrame->argumentCount())
93         return jsUndefined();
94
95     JSValue program = callFrame->argument(0);
96     if (!program.isString())
97         return program;
98     
99     TopCallFrameSetter topCallFrame(callFrame->vm(), callFrame);
100     String programSource = asString(program)->value(callFrame);
101     if (callFrame->hadException())
102         return JSValue();
103     
104     CallFrame* callerFrame = callFrame->callerFrame();
105     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
106     JSScope* callerScopeChain = callerFrame->uncheckedR(callerCodeBlock->scopeRegister().offset()).Register::scope();
107     EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
108
109     if (!eval) {
110         if (!callerCodeBlock->isStrictMode()) {
111             // FIXME: We can use the preparser in strict mode, we just need additional logic
112             // to prevent duplicates.
113             if (programSource.is8Bit()) {
114                 LiteralParser<LChar> preparser(callFrame, programSource.characters8(), programSource.length(), NonStrictJSON);
115                 if (JSValue parsedObject = preparser.tryLiteralParse())
116                     return parsedObject;
117             } else {
118                 LiteralParser<UChar> preparser(callFrame, programSource.characters16(), programSource.length(), NonStrictJSON);
119                 if (JSValue parsedObject = preparser.tryLiteralParse())
120                     return parsedObject;                
121             }
122         }
123         
124         // If the literal parser bailed, it should not have thrown exceptions.
125         ASSERT(!callFrame->vm().exception());
126
127         eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
128         if (!eval)
129             return jsUndefined();
130     }
131
132     JSValue thisValue = callerFrame->thisValue();
133     Interpreter* interpreter = callFrame->vm().interpreter;
134     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
135 }
136
137 CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, unsigned numUsedStackSlots, uint32_t firstVarArgOffset)
138 {
139     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
140         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
141         if (argumentCountIncludingThis > firstVarArgOffset)
142             argumentCountIncludingThis -= firstVarArgOffset;
143         else
144             argumentCountIncludingThis = 1;
145         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
146         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
147         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
148             throwStackOverflowError(callFrame);
149             return 0;
150         }
151         return newCallFrame;
152     }
153
154     if (arguments.isUndefinedOrNull()) {
155         unsigned argumentCountIncludingThis = 1;
156         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  numUsedStackSlots + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
157         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
158         if (!stack->ensureCapacityFor(newCallFrame->registers())) {
159             throwStackOverflowError(callFrame);
160             return 0;
161         }
162         return newCallFrame;
163     }
164
165     if (!arguments.isObject()) {
166         callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
167         return 0;
168     }
169
170     if (asObject(arguments)->classInfo() == Arguments::info()) {
171         Arguments* argsObject = asArguments(arguments);
172         unsigned argCount = argsObject->length(callFrame);
173         if (argCount >= firstVarArgOffset)
174             argCount -= firstVarArgOffset;
175         else
176             argCount = 0;
177         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
178         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
179         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
180             throwStackOverflowError(callFrame);
181             return 0;
182         }
183         return newCallFrame;
184     }
185
186     if (isJSArray(arguments)) {
187         JSArray* array = asArray(arguments);
188         unsigned argCount = array->length();
189         if (argCount >= firstVarArgOffset)
190             argCount -= firstVarArgOffset;
191         else
192             argCount = 0;
193         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
194         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
195         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
196             throwStackOverflowError(callFrame);
197             return 0;
198         }
199         return newCallFrame;
200     }
201
202     JSObject* argObject = asObject(arguments);
203     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
204     if (argCount >= firstVarArgOffset)
205         argCount -= firstVarArgOffset;
206     else
207         argCount = 0;
208     unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numUsedStackSlots + argCount + 1 + JSStack::CallFrameHeaderSize);
209     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
210     if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
211         throwStackOverflowError(callFrame);
212         return 0;
213     }
214     return newCallFrame;
215 }
216
217 void loadVarargs(CallFrame* callFrame, VirtualRegister firstElementDest, VirtualRegister countDest, JSValue arguments, uint32_t firstVarArgOffset)
218 {
219     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
220         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
221         if (argumentCountIncludingThis > firstVarArgOffset)
222             argumentCountIncludingThis -= firstVarArgOffset;
223         else
224             argumentCountIncludingThis = 1;
225         callFrame->r(countDest).payload() = argumentCountIncludingThis;
226         for (size_t i = firstVarArgOffset; i < callFrame->argumentCount(); ++i)
227             callFrame->r(firstElementDest + i - firstVarArgOffset) = callFrame->argumentAfterCapture(i);
228         return;
229     }
230     
231     if (arguments.isUndefinedOrNull()) {
232         callFrame->r(countDest).payload() = 1;
233         return;
234     }
235     
236     if (asObject(arguments)->classInfo() == Arguments::info()) {
237         Arguments* argsObject = asArguments(arguments);
238         unsigned argCount = argsObject->length(callFrame);
239         if (argCount >= firstVarArgOffset) {
240             argCount -= firstVarArgOffset;
241             callFrame->r(countDest).payload() = argCount + 1;
242             argsObject->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
243         } else
244             callFrame->r(countDest).payload() = 1;
245         return;
246     }
247     
248     if (isJSArray(arguments)) {
249         JSArray* array = asArray(arguments);
250         unsigned argCount = array->length();
251         if (argCount >= firstVarArgOffset) {
252             argCount -= firstVarArgOffset;
253             callFrame->r(countDest).payload() = argCount + 1;
254             array->copyToArguments(callFrame, firstElementDest, argCount, firstVarArgOffset);
255         } else
256             callFrame->r(countDest).payload() = 1;
257         return;
258     }
259     
260     JSObject* argObject = asObject(arguments);
261     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
262     if (argCount >= firstVarArgOffset) {
263         argCount -= firstVarArgOffset;
264         callFrame->r(countDest).payload() = argCount + 1;
265     } else
266         callFrame->r(countDest).payload() = 1;
267
268     for (size_t i = 0; i < argCount; ++i) {
269         callFrame->r(firstElementDest + i) = asObject(arguments)->get(callFrame, i + firstVarArgOffset);
270         if (UNLIKELY(callFrame->vm().exception()))
271             return;
272     }
273 }
274
275 void setupVarargsFrame(CallFrame* callFrame, CallFrame* newCallFrame, JSValue arguments, uint32_t firstVarArgOffset)
276 {
277     VirtualRegister calleeFrameOffset(newCallFrame - callFrame);
278     
279     loadVarargs(
280         callFrame,
281         calleeFrameOffset + CallFrame::argumentOffset(0),
282         calleeFrameOffset + JSStack::ArgumentCount,
283         arguments, firstVarArgOffset);
284 }
285
286 void setupVarargsFrameAndSetThis(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments, uint32_t firstVarArgOffset)
287 {
288     setupVarargsFrame(callFrame, newCallFrame, arguments, firstVarArgOffset);
289     newCallFrame->setThisValue(thisValue);
290 }
291
292 Interpreter::Interpreter(VM& vm)
293     : m_sampleEntryDepth(0)
294     , m_vm(vm)
295     , m_stack(vm)
296     , m_errorHandlingModeReentry(0)
297 #if !ASSERT_DISABLED
298     , m_initialized(false)
299 #endif
300 {
301 }
302
303 Interpreter::~Interpreter()
304 {
305 }
306
307 void Interpreter::initialize(bool canUseJIT)
308 {
309     UNUSED_PARAM(canUseJIT);
310
311 #if ENABLE(COMPUTED_GOTO_OPCODES)
312     m_opcodeTable = LLInt::opcodeMap();
313     for (int i = 0; i < numOpcodeIDs; ++i)
314         m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
315 #endif
316
317 #if !ASSERT_DISABLED
318     m_initialized = true;
319 #endif
320
321 #if ENABLE(OPCODE_SAMPLING)
322     enableSampler();
323 #endif
324 }
325
326 #ifdef NDEBUG
327
328 void Interpreter::dumpCallFrame(CallFrame*)
329 {
330 }
331
332 #else
333
334 void Interpreter::dumpCallFrame(CallFrame* callFrame)
335 {
336     callFrame->codeBlock()->dumpBytecode();
337     dumpRegisters(callFrame);
338 }
339
340 class DumpRegisterFunctor {
341 public:
342     DumpRegisterFunctor(const Register*& it)
343         : m_hasSkippedFirstFrame(false)
344         , m_it(it)
345     {
346     }
347
348     StackVisitor::Status operator()(StackVisitor& visitor)
349     {
350         if (!m_hasSkippedFirstFrame) {
351             m_hasSkippedFirstFrame = true;
352             return StackVisitor::Continue;
353         }
354
355         unsigned line = 0;
356         unsigned unusedColumn = 0;
357         visitor->computeLineAndColumn(line, unusedColumn);
358         dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", m_it, visitor->bytecodeOffset(), line);
359         --m_it;
360         return StackVisitor::Done;
361     }
362
363 private:
364     bool m_hasSkippedFirstFrame;
365     const Register*& m_it;
366 };
367
368 void Interpreter::dumpRegisters(CallFrame* callFrame)
369 {
370     dataLogF("Register frame: \n\n");
371     dataLogF("-----------------------------------------------------------------------------\n");
372     dataLogF("            use            |   address  |                value               \n");
373     dataLogF("-----------------------------------------------------------------------------\n");
374
375     CodeBlock* codeBlock = callFrame->codeBlock();
376     const Register* it;
377     const Register* end;
378
379     it = callFrame->registers() + JSStack::ThisArgument + callFrame->argumentCount();
380     end = callFrame->registers() + JSStack::ThisArgument - 1;
381     while (it > end) {
382         JSValue v = it->jsValue();
383         int registerNumber = it - callFrame->registers();
384         String name = codeBlock->nameForRegister(VirtualRegister(registerNumber));
385         dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
386         --it;
387     }
388     
389     dataLogF("-----------------------------------------------------------------------------\n");
390     dataLogF("[ArgumentCount]            | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount());
391     --it;
392     dataLogF("[CallerFrame]              | %10p | %p \n", it, callFrame->callerFrame());
393     --it;
394     dataLogF("[Callee]                   | %10p | %p \n", it, callFrame->callee());
395     --it;
396     // FIXME: Remove the next decrement when the ScopeChain slot is removed from the call header
397     --it;
398 #if ENABLE(JIT)
399     AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm());
400     if (pc.hasJITReturnAddress())
401         dataLogF("[ReturnJITPC]              | %10p | %p \n", it, pc.jitReturnAddress().value());
402 #endif
403
404     DumpRegisterFunctor functor(it);
405     callFrame->iterate(functor);
406
407     dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
408     --it;
409     dataLogF("-----------------------------------------------------------------------------\n");
410
411     end = it - codeBlock->m_numVars;
412     if (it != end) {
413         do {
414             JSValue v = it->jsValue();
415             int registerNumber = it - callFrame->registers();
416             String name = codeBlock->nameForRegister(VirtualRegister(registerNumber));
417             dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
418             --it;
419         } while (it != end);
420     }
421     dataLogF("-----------------------------------------------------------------------------\n");
422
423     end = it - codeBlock->m_numCalleeRegisters + codeBlock->m_numVars;
424     if (it != end) {
425         do {
426             JSValue v = (*it).jsValue();
427             int registerNumber = it - callFrame->registers();
428             dataLogF("[r% 3d]                     | %10p | %-16s 0x%lld \n", registerNumber, it, toCString(v).data(), (long long)JSValue::encode(v));
429             --it;
430         } while (it != end);
431     }
432     dataLogF("-----------------------------------------------------------------------------\n");
433 }
434
435 #endif
436
437 bool Interpreter::isOpcode(Opcode opcode)
438 {
439 #if ENABLE(COMPUTED_GOTO_OPCODES)
440     return opcode != HashTraits<Opcode>::emptyValue()
441         && !HashTraits<Opcode>::isDeletedValue(opcode)
442         && m_opcodeIDTable.contains(opcode);
443 #else
444     return opcode >= 0 && opcode <= op_end;
445 #endif
446 }
447
448 static bool unwindCallFrame(StackVisitor& visitor)
449 {
450     CallFrame* callFrame = visitor->callFrame();
451     if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) {
452         ClearExceptionScope scope(&callFrame->vm());
453         if (jsDynamicCast<JSFunction*>(callFrame->callee()))
454             debugger->returnEvent(callFrame);
455         else
456             debugger->didExecuteProgram(callFrame);
457         ASSERT(!callFrame->hadException());
458     }
459
460     if (CodeBlock* codeBlock = visitor->codeBlock()) {
461         if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
462 #if ENABLE(DFG_JIT)
463             RELEASE_ASSERT(!visitor->isInlinedFrame());
464 #endif
465         }
466
467         if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
468             if (Arguments* arguments = visitor->existingArguments()) {
469 #if ENABLE(DFG_JIT)
470                 if (visitor->isInlinedFrame())
471                     arguments->tearOff(callFrame, visitor->inlineCallFrame());
472                 else
473 #endif
474                     arguments->tearOff(callFrame);
475             }
476         }
477     }
478
479     return !visitor->callerIsVMEntryFrame();
480 }
481
482 static StackFrameCodeType getStackFrameCodeType(StackVisitor& visitor)
483 {
484     switch (visitor->codeType()) {
485     case StackVisitor::Frame::Eval:
486         return StackFrameEvalCode;
487     case StackVisitor::Frame::Function:
488         return StackFrameFunctionCode;
489     case StackVisitor::Frame::Global:
490         return StackFrameGlobalCode;
491     case StackVisitor::Frame::Native:
492         ASSERT_NOT_REACHED();
493         return StackFrameNativeCode;
494     }
495     RELEASE_ASSERT_NOT_REACHED();
496     return StackFrameGlobalCode;
497 }
498
499 void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column)
500 {
501     if (!codeBlock) {
502         line = 0;
503         column = 0;
504         return;
505     }
506
507     int divot = 0;
508     int unusedStartOffset = 0;
509     int unusedEndOffset = 0;
510     unsigned divotLine = 0;
511     unsigned divotColumn = 0;
512     expressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
513
514     line = divotLine + lineOffset;
515     column = divotColumn + (divotLine ? 1 : firstLineColumnOffset);
516 }
517
518 void StackFrame::expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
519 {
520     codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
521     divot += characterOffset;
522 }
523
524 String StackFrame::toString(CallFrame* callFrame)
525 {
526     StringBuilder traceBuild;
527     String functionName = friendlyFunctionName(callFrame);
528     String sourceURL = friendlySourceURL();
529     traceBuild.append(functionName);
530     if (!sourceURL.isEmpty()) {
531         if (!functionName.isEmpty())
532             traceBuild.append('@');
533         traceBuild.append(sourceURL);
534         if (codeType != StackFrameNativeCode) {
535             unsigned line;
536             unsigned column;
537             computeLineAndColumn(line, column);
538
539             traceBuild.append(':');
540             traceBuild.appendNumber(line);
541             traceBuild.append(':');
542             traceBuild.appendNumber(column);
543         }
544     }
545     return traceBuild.toString().impl();
546 }
547
548 class GetStackTraceFunctor {
549 public:
550     GetStackTraceFunctor(VM& vm, Vector<StackFrame>& results, size_t remainingCapacity)
551         : m_vm(vm)
552         , m_results(results)
553         , m_remainingCapacityForFrameCapture(remainingCapacity)
554     {
555     }
556
557     StackVisitor::Status operator()(StackVisitor& visitor)
558     {
559         VM& vm = m_vm;
560         if (m_remainingCapacityForFrameCapture) {
561             if (visitor->isJSFrame() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
562                 CodeBlock* codeBlock = visitor->codeBlock();
563                 StackFrame s = {
564                     Strong<JSObject>(vm, visitor->callee()),
565                     getStackFrameCodeType(visitor),
566                     Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()),
567                     Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
568                     codeBlock->source(),
569                     codeBlock->ownerExecutable()->lineNo(),
570                     codeBlock->firstLineColumnOffset(),
571                     codeBlock->sourceOffset(),
572                     visitor->bytecodeOffset(),
573                     visitor->sourceURL()
574                 };
575                 m_results.append(s);
576             } else {
577                 StackFrame s = { Strong<JSObject>(vm, visitor->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
578                 m_results.append(s);
579             }
580     
581             m_remainingCapacityForFrameCapture--;
582             return StackVisitor::Continue;
583         }
584         return StackVisitor::Done;
585     }
586
587 private:
588     VM& m_vm;
589     Vector<StackFrame>& m_results;
590     size_t m_remainingCapacityForFrameCapture;
591 };
592
593 void Interpreter::getStackTrace(Vector<StackFrame>& results, size_t maxStackSize)
594 {
595     VM& vm = m_vm;
596     CallFrame* callFrame = vm.topCallFrame;
597     if (!callFrame)
598         return;
599
600     GetStackTraceFunctor functor(vm, results, maxStackSize);
601     callFrame->iterate(functor);
602 }
603
604 JSString* Interpreter::stackTraceAsString(ExecState* exec, Vector<StackFrame> stackTrace)
605 {
606     // FIXME: JSStringJoiner could be more efficient than StringBuilder here.
607     StringBuilder builder;
608     for (unsigned i = 0; i < stackTrace.size(); i++) {
609         builder.append(String(stackTrace[i].toString(exec)));
610         if (i != stackTrace.size() - 1)
611             builder.append('\n');
612     }
613     return jsString(&exec->vm(), builder.toString());
614 }
615
616 class GetExceptionHandlerFunctor {
617 public:
618     GetExceptionHandlerFunctor()
619         : m_handler(0)
620     {
621     }
622
623     HandlerInfo* handler() { return m_handler; }
624
625     StackVisitor::Status operator()(StackVisitor& visitor)
626     {
627         CodeBlock* codeBlock = visitor->codeBlock();
628         if (!codeBlock)
629             return StackVisitor::Continue;
630
631         unsigned bytecodeOffset = visitor->bytecodeOffset();
632         m_handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
633         if (m_handler)
634             return StackVisitor::Done;
635
636         return StackVisitor::Continue;
637     }
638
639 private:
640     HandlerInfo* m_handler;
641 };
642
643 class UnwindFunctor {
644 public:
645     UnwindFunctor(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
646         : m_vmEntryFrame(vmEntryFrame)
647         , m_callFrame(callFrame)
648         , m_isTermination(isTermination)
649         , m_codeBlock(codeBlock)
650         , m_handler(handler)
651     {
652     }
653
654     StackVisitor::Status operator()(StackVisitor& visitor)
655     {
656         VM& vm = m_callFrame->vm();
657         m_vmEntryFrame = visitor->vmEntryFrame();
658         m_callFrame = visitor->callFrame();
659         m_codeBlock = visitor->codeBlock();
660         unsigned bytecodeOffset = visitor->bytecodeOffset();
661
662         if (m_isTermination || !(m_handler = m_codeBlock ? m_codeBlock->handlerForBytecodeOffset(bytecodeOffset) : nullptr)) {
663             if (!unwindCallFrame(visitor)) {
664                 if (LegacyProfiler* profiler = vm.enabledProfiler())
665                     profiler->exceptionUnwind(m_callFrame);
666                 return StackVisitor::Done;
667             }
668         } else
669             return StackVisitor::Done;
670
671         return StackVisitor::Continue;
672     }
673
674 private:
675     VMEntryFrame*& m_vmEntryFrame;
676     CallFrame*& m_callFrame;
677     bool m_isTermination;
678     CodeBlock*& m_codeBlock;
679     HandlerInfo*& m_handler;
680 };
681
682 NEVER_INLINE HandlerInfo* Interpreter::unwind(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, JSValue& exceptionValue)
683 {
684     CodeBlock* codeBlock = callFrame->codeBlock();
685     bool isTermination = false;
686
687     ASSERT(!exceptionValue.isEmpty());
688     ASSERT(!exceptionValue.isCell() || exceptionValue.asCell());
689     // This shouldn't be possible (hence the assertions), but we're already in the slowest of
690     // slow cases, so let's harden against it anyway to be safe.
691     if (exceptionValue.isEmpty() || (exceptionValue.isCell() && !exceptionValue.asCell()))
692         exceptionValue = jsNull();
693
694     if (exceptionValue.isObject())
695         isTermination = isTerminatedExecutionException(asObject(exceptionValue));
696
697     ASSERT(callFrame->vm().exceptionStack().size());
698
699     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
700     if (debugger && debugger->needsExceptionCallbacks()) {
701         // We need to clear the exception and the exception stack here in order to see if a new exception happens.
702         // Afterwards, the values are put back to continue processing this error.
703         ClearExceptionScope scope(&callFrame->vm());
704         // This code assumes that if the debugger is enabled then there is no inlining.
705         // If that assumption turns out to be false then we'll ignore the inlined call
706         // frames.
707         // https://bugs.webkit.org/show_bug.cgi?id=121754
708
709         bool hasHandler;
710         if (isTermination)
711             hasHandler = false;
712         else {
713             GetExceptionHandlerFunctor functor;
714             callFrame->iterate(functor);
715             hasHandler = !!functor.handler();
716         }
717
718         debugger->exception(callFrame, exceptionValue, hasHandler);
719         ASSERT(!callFrame->hadException());
720     }
721
722     // Calculate an exception handler vPC, unwinding call frames as necessary.
723     HandlerInfo* handler = 0;
724     VM& vm = callFrame->vm();
725     ASSERT(callFrame == vm.topCallFrame);
726     UnwindFunctor functor(vmEntryFrame, callFrame, isTermination, codeBlock, handler);
727     callFrame->iterate(functor);
728     if (!handler)
729         return 0;
730
731     if (LegacyProfiler* profiler = vm.enabledProfiler())
732         profiler->exceptionUnwind(callFrame);
733
734     // Unwind the scope chain within the exception handler's call frame.
735     int targetScopeDepth = handler->scopeDepth;
736     if (codeBlock->needsActivation() && callFrame->hasActivation())
737         ++targetScopeDepth;
738
739     int scopeRegisterOffset = codeBlock->scopeRegister().offset();
740     JSScope* scope = callFrame->scope(scopeRegisterOffset);
741     int scopeDelta = scope->depth() - targetScopeDepth;
742     RELEASE_ASSERT(scopeDelta >= 0);
743
744     while (scopeDelta--)
745         scope = scope->next();
746
747     callFrame->setScope(scopeRegisterOffset, scope);
748
749     return handler;
750 }
751
752 static inline JSValue checkedReturn(JSValue returnValue)
753 {
754     ASSERT(returnValue);
755     return returnValue;
756 }
757
758 static inline JSObject* checkedReturn(JSObject* returnValue)
759 {
760     ASSERT(returnValue);
761     return returnValue;
762 }
763
764 class SamplingScope {
765 public:
766     SamplingScope(Interpreter* interpreter)
767         : m_interpreter(interpreter)
768     {
769         interpreter->startSampling();
770     }
771     ~SamplingScope()
772     {
773         m_interpreter->stopSampling();
774     }
775 private:
776     Interpreter* m_interpreter;
777 };
778
779 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
780 {
781     SamplingScope samplingScope(this);
782
783     JSScope* scope = thisObj->globalObject();
784     VM& vm = *scope->vm();
785
786     ASSERT(!vm.exception());
787     ASSERT(!vm.isCollectorBusy());
788     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
789     if (vm.isCollectorBusy())
790         return jsNull();
791
792     if (!vm.isSafeToRecurse())
793         return checkedReturn(throwStackOverflowError(callFrame));
794
795     // First check if the "program" is actually just a JSON object. If so,
796     // we'll handle the JSON object here. Else, we'll handle real JS code
797     // below at failedJSONP.
798
799     Vector<JSONPData> JSONPData;
800     bool parseResult;
801     const String programSource = program->source().toString();
802     if (programSource.isNull())
803         return jsUndefined();
804     if (programSource.is8Bit()) {
805         LiteralParser<LChar> literalParser(callFrame, programSource.characters8(), programSource.length(), JSONP);
806         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
807     } else {
808         LiteralParser<UChar> literalParser(callFrame, programSource.characters16(), programSource.length(), JSONP);
809         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
810     }
811
812     if (parseResult) {
813         JSGlobalObject* globalObject = scope->globalObject();
814         JSValue result;
815         for (unsigned entry = 0; entry < JSONPData.size(); entry++) {
816             Vector<JSONPPathEntry> JSONPPath;
817             JSONPPath.swap(JSONPData[entry].m_path);
818             JSValue JSONPValue = JSONPData[entry].m_value.get();
819             if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
820                 globalObject->addVar(callFrame, JSONPPath[0].m_pathEntryName);
821                 PutPropertySlot slot(globalObject);
822                 globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
823                 result = jsUndefined();
824                 continue;
825             }
826             JSValue baseObject(globalObject);
827             for (unsigned i = 0; i < JSONPPath.size() - 1; i++) {
828                 ASSERT(JSONPPath[i].m_type != JSONPPathEntryTypeDeclare);
829                 switch (JSONPPath[i].m_type) {
830                 case JSONPPathEntryTypeDot: {
831                     if (i == 0) {
832                         PropertySlot slot(globalObject);
833                         if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
834                             if (entry)
835                                 return callFrame->vm().throwException(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
836                             goto failedJSONP;
837                         }
838                         baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
839                     } else
840                         baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathEntryName);
841                     if (callFrame->hadException())
842                         return jsUndefined();
843                     continue;
844                 }
845                 case JSONPPathEntryTypeLookup: {
846                     baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathIndex);
847                     if (callFrame->hadException())
848                         return jsUndefined();
849                     continue;
850                 }
851                 default:
852                     RELEASE_ASSERT_NOT_REACHED();
853                     return jsUndefined();
854                 }
855             }
856             PutPropertySlot slot(baseObject);
857             switch (JSONPPath.last().m_type) {
858             case JSONPPathEntryTypeCall: {
859                 JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
860                 if (callFrame->hadException())
861                     return jsUndefined();
862                 CallData callData;
863                 CallType callType = getCallData(function, callData);
864                 if (callType == CallTypeNone)
865                     return callFrame->vm().throwException(callFrame, createNotAFunctionError(callFrame, function));
866                 MarkedArgumentBuffer jsonArg;
867                 jsonArg.append(JSONPValue);
868                 JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
869                 JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
870                 if (callFrame->hadException())
871                     return jsUndefined();
872                 break;
873             }
874             case JSONPPathEntryTypeDot: {
875                 baseObject.put(callFrame, JSONPPath.last().m_pathEntryName, JSONPValue, slot);
876                 if (callFrame->hadException())
877                     return jsUndefined();
878                 break;
879             }
880             case JSONPPathEntryTypeLookup: {
881                 baseObject.putByIndex(callFrame, JSONPPath.last().m_pathIndex, JSONPValue, slot.isStrictMode());
882                 if (callFrame->hadException())
883                     return jsUndefined();
884                 break;
885             }
886             default:
887                 RELEASE_ASSERT_NOT_REACHED();
888                     return jsUndefined();
889             }
890             result = JSONPValue;
891         }
892         return result;
893     }
894 failedJSONP:
895     // If we get here, then we have already proven that the script is not a JSON
896     // object.
897
898     VMEntryScope entryScope(vm, scope->globalObject());
899
900     // Compile source to bytecode if necessary:
901     if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
902         return checkedReturn(callFrame->vm().throwException(callFrame, error));
903
904     if (JSObject* error = program->prepareForExecution(callFrame, nullptr, &scope, CodeForCall))
905         return checkedReturn(callFrame->vm().throwException(callFrame, error));
906
907     ProgramCodeBlock* codeBlock = program->codeBlock();
908
909     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
910         return throwTerminatedExecutionException(callFrame);
911
912     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
913
914     ProtoCallFrame protoCallFrame;
915     protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), thisObj, 1);
916
917     if (LegacyProfiler* profiler = vm.enabledProfiler())
918         profiler->willExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
919
920     // Execute the code:
921     JSValue result;
922     {
923         SamplingTool::CallRecord callRecord(m_sampler.get());
924         Watchdog::Scope watchdogScope(vm.watchdog.get());
925
926         result = program->generatedJITCode()->execute(&vm, &protoCallFrame);
927     }
928
929     if (LegacyProfiler* profiler = vm.enabledProfiler())
930         profiler->didExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
931
932     return checkedReturn(result);
933 }
934
935 JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
936 {
937     VM& vm = callFrame->vm();
938     ASSERT(!callFrame->hadException());
939     ASSERT(!vm.isCollectorBusy());
940     if (vm.isCollectorBusy())
941         return jsNull();
942
943     bool isJSCall = (callType == CallTypeJS);
944     JSScope* scope = nullptr;
945     CodeBlock* newCodeBlock;
946     size_t argsCount = 1 + args.size(); // implicit "this" parameter
947
948     JSGlobalObject* globalObject;
949
950     if (isJSCall) {
951         scope = callData.js.scope;
952         globalObject = scope->globalObject();
953     } else {
954         ASSERT(callType == CallTypeHost);
955         globalObject = function->globalObject();
956     }
957
958     VMEntryScope entryScope(vm, globalObject);
959     if (!vm.isSafeToRecurse())
960         return checkedReturn(throwStackOverflowError(callFrame));
961
962     if (isJSCall) {
963         // Compile the callee:
964         JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(function), &scope, CodeForCall);
965         if (UNLIKELY(!!compileError)) {
966             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
967         }
968         newCodeBlock = callData.js.functionExecutable->codeBlockForCall();
969         ASSERT(!!newCodeBlock);
970         newCodeBlock->m_shouldAlwaysBeInlined = false;
971     } else
972         newCodeBlock = 0;
973
974     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
975         return throwTerminatedExecutionException(callFrame);
976
977     ProtoCallFrame protoCallFrame;
978     protoCallFrame.init(newCodeBlock, function, thisValue, argsCount, args.data());
979
980     if (LegacyProfiler* profiler = vm.enabledProfiler())
981         profiler->willExecute(callFrame, function);
982
983     JSValue result;
984     {
985         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
986         Watchdog::Scope watchdogScope(vm.watchdog.get());
987
988         // Execute the code:
989         if (isJSCall)
990             result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame);
991         else {
992             result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));
993             if (callFrame->hadException())
994                 result = jsNull();
995         }
996     }
997
998     if (LegacyProfiler* profiler = vm.enabledProfiler())
999         profiler->didExecute(callFrame, function);
1000
1001     return checkedReturn(result);
1002 }
1003
1004 JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
1005 {
1006     VM& vm = callFrame->vm();
1007     ASSERT(!callFrame->hadException());
1008     ASSERT(!vm.isCollectorBusy());
1009     // We throw in this case because we have to return something "valid" but we're
1010     // already in an invalid state.
1011     if (vm.isCollectorBusy())
1012         return checkedReturn(throwStackOverflowError(callFrame));
1013
1014     bool isJSConstruct = (constructType == ConstructTypeJS);
1015     JSScope* scope = nullptr;
1016     CodeBlock* newCodeBlock;
1017     size_t argsCount = 1 + args.size(); // implicit "this" parameter
1018
1019     JSGlobalObject* globalObject;
1020
1021     if (isJSConstruct) {
1022         scope = constructData.js.scope;
1023         globalObject = scope->globalObject();
1024     } else {
1025         ASSERT(constructType == ConstructTypeHost);
1026         globalObject = constructor->globalObject();
1027     }
1028
1029     VMEntryScope entryScope(vm, globalObject);
1030     if (!vm.isSafeToRecurse())
1031         return checkedReturn(throwStackOverflowError(callFrame));
1032
1033     if (isJSConstruct) {
1034         // Compile the callee:
1035         JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(constructor), &scope, CodeForConstruct);
1036         if (UNLIKELY(!!compileError)) {
1037             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1038         }
1039         newCodeBlock = constructData.js.functionExecutable->codeBlockForConstruct();
1040         ASSERT(!!newCodeBlock);
1041         newCodeBlock->m_shouldAlwaysBeInlined = false;
1042     } else
1043         newCodeBlock = 0;
1044
1045     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
1046         return throwTerminatedExecutionException(callFrame);
1047
1048     ProtoCallFrame protoCallFrame;
1049     protoCallFrame.init(newCodeBlock, constructor, jsUndefined(), argsCount, args.data());
1050
1051     if (LegacyProfiler* profiler = vm.enabledProfiler())
1052         profiler->willExecute(callFrame, constructor);
1053
1054     JSValue result;
1055     {
1056         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
1057         Watchdog::Scope watchdogScope(vm.watchdog.get());
1058
1059         // Execute the code.
1060         if (isJSConstruct)
1061             result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame);
1062         else {
1063             result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));
1064
1065             if (!callFrame->hadException())
1066                 RELEASE_ASSERT(result.isObject());
1067         }
1068     }
1069
1070     if (LegacyProfiler* profiler = vm.enabledProfiler())
1071         profiler->didExecute(callFrame, constructor);
1072
1073     if (callFrame->hadException())
1074         return 0;
1075     ASSERT(result.isObject());
1076     return checkedReturn(asObject(result));
1077 }
1078
1079 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
1080 {
1081     VM& vm = *scope->vm();
1082     ASSERT(!vm.exception());
1083     
1084     if (vm.isCollectorBusy())
1085         return CallFrameClosure();
1086
1087     // Compile the callee:
1088     JSObject* error = functionExecutable->prepareForExecution(callFrame, function, &scope, CodeForCall);
1089     if (error) {
1090         callFrame->vm().throwException(callFrame, error);
1091         return CallFrameClosure();
1092     }
1093     CodeBlock* newCodeBlock = functionExecutable->codeBlockForCall();
1094     newCodeBlock->m_shouldAlwaysBeInlined = false;
1095
1096     size_t argsCount = argumentCountIncludingThis;
1097
1098     protoCallFrame->init(newCodeBlock, function, jsUndefined(), argsCount, args);
1099     // Return the successful closure:
1100     CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
1101     return result;
1102 }
1103
1104 JSValue Interpreter::execute(CallFrameClosure& closure) 
1105 {
1106     VM& vm = *closure.vm;
1107     SamplingScope samplingScope(this);
1108     
1109     ASSERT(!vm.isCollectorBusy());
1110     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
1111     if (vm.isCollectorBusy())
1112         return jsNull();
1113
1114     StackStats::CheckPoint stackCheckPoint;
1115
1116     if (LegacyProfiler* profiler = vm.enabledProfiler())
1117         profiler->willExecute(closure.oldCallFrame, closure.function);
1118
1119     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(closure.oldCallFrame)))
1120         return throwTerminatedExecutionException(closure.oldCallFrame);
1121
1122     // Execute the code:
1123     JSValue result;
1124     {
1125         SamplingTool::CallRecord callRecord(m_sampler.get());
1126         Watchdog::Scope watchdogScope(vm.watchdog.get());
1127
1128         result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.protoCallFrame);
1129     }
1130
1131     if (LegacyProfiler* profiler = vm.enabledProfiler())
1132         profiler->didExecute(closure.oldCallFrame, closure.function);
1133
1134     return checkedReturn(result);
1135 }
1136
1137 JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
1138 {
1139     VM& vm = *scope->vm();
1140     SamplingScope samplingScope(this);
1141     
1142     ASSERT(scope->vm() == &callFrame->vm());
1143     ASSERT(!vm.exception());
1144     ASSERT(!vm.isCollectorBusy());
1145     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
1146     if (vm.isCollectorBusy())
1147         return jsNull();
1148
1149     VMEntryScope entryScope(vm, scope->globalObject());
1150     if (!vm.isSafeToRecurse())
1151         return checkedReturn(throwStackOverflowError(callFrame));        
1152
1153     unsigned numVariables = eval->numVariables();
1154     int numFunctions = eval->numberOfFunctionDecls();
1155
1156     JSScope* variableObject;
1157     if ((numVariables || numFunctions) && eval->isStrictMode()) {
1158         scope = StrictEvalActivation::create(callFrame, scope);
1159         variableObject = scope;
1160     } else {
1161         for (JSScope* node = scope; ; node = node->next()) {
1162             RELEASE_ASSERT(node);
1163             if (node->isVariableObject() && !node->isNameScopeObject()) {
1164                 variableObject = node;
1165                 break;
1166             }
1167         }
1168     }
1169
1170     JSObject* compileError = eval->prepareForExecution(callFrame, nullptr, &scope, CodeForCall);
1171     if (UNLIKELY(!!compileError))
1172         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1173     EvalCodeBlock* codeBlock = eval->codeBlock();
1174
1175     if (numVariables || numFunctions) {
1176         BatchedTransitionOptimizer optimizer(vm, variableObject);
1177         if (variableObject->next())
1178             variableObject->globalObject()->varInjectionWatchpoint()->fireAll("Executed eval, fired VarInjection watchpoint");
1179
1180         for (unsigned i = 0; i < numVariables; ++i) {
1181             const Identifier& ident = codeBlock->variable(i);
1182             if (!variableObject->hasProperty(callFrame, ident)) {
1183                 PutPropertySlot slot(variableObject);
1184                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
1185             }
1186         }
1187
1188         for (int i = 0; i < numFunctions; ++i) {
1189             FunctionExecutable* function = codeBlock->functionDecl(i);
1190             PutPropertySlot slot(variableObject);
1191             variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
1192         }
1193     }
1194
1195     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
1196         return throwTerminatedExecutionException(callFrame);
1197
1198     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1199
1200     ProtoCallFrame protoCallFrame;
1201     protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), thisValue, 1);
1202
1203     if (LegacyProfiler* profiler = vm.enabledProfiler())
1204         profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
1205
1206     // Execute the code:
1207     JSValue result;
1208     {
1209         SamplingTool::CallRecord callRecord(m_sampler.get());
1210         Watchdog::Scope watchdogScope(vm.watchdog.get());
1211
1212         result = eval->generatedJITCode()->execute(&vm, &protoCallFrame);
1213     }
1214
1215     if (LegacyProfiler* profiler = vm.enabledProfiler())
1216         profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
1217
1218     return checkedReturn(result);
1219 }
1220
1221 NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID)
1222 {
1223     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
1224     if (!debugger)
1225         return;
1226
1227     ASSERT(callFrame->codeBlock()->hasDebuggerRequests());
1228     ASSERT(!callFrame->hadException());
1229
1230     switch (debugHookID) {
1231         case DidEnterCallFrame:
1232             debugger->callEvent(callFrame);
1233             break;
1234         case WillLeaveCallFrame:
1235             debugger->returnEvent(callFrame);
1236             break;
1237         case WillExecuteStatement:
1238             debugger->atStatement(callFrame);
1239             break;
1240         case WillExecuteProgram:
1241             debugger->willExecuteProgram(callFrame);
1242             break;
1243         case DidExecuteProgram:
1244             debugger->didExecuteProgram(callFrame);
1245             break;
1246         case DidReachBreakpoint:
1247             debugger->didReachBreakpoint(callFrame);
1248             break;
1249     }
1250     ASSERT(!callFrame->hadException());
1251 }    
1252
1253 void Interpreter::enableSampler()
1254 {
1255 #if ENABLE(OPCODE_SAMPLING)
1256     if (!m_sampler) {
1257         m_sampler = std::make_unique<SamplingTool>(this);
1258         m_sampler->setup();
1259     }
1260 #endif
1261 }
1262 void Interpreter::dumpSampleData(ExecState* exec)
1263 {
1264 #if ENABLE(OPCODE_SAMPLING)
1265     if (m_sampler)
1266         m_sampler->dump(exec);
1267 #else
1268     UNUSED_PARAM(exec);
1269 #endif
1270 }
1271 void Interpreter::startSampling()
1272 {
1273 #if ENABLE(SAMPLING_THREAD)
1274     if (!m_sampleEntryDepth)
1275         SamplingThread::start();
1276
1277     m_sampleEntryDepth++;
1278 #endif
1279 }
1280 void Interpreter::stopSampling()
1281 {
1282 #if ENABLE(SAMPLING_THREAD)
1283     m_sampleEntryDepth--;
1284     if (!m_sampleEntryDepth)
1285         SamplingThread::stop();
1286 #endif
1287 }
1288
1289 } // namespace JSC