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