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