[ES6] implement block scoping to enable 'let'
[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 "JSNameScope.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
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     // Unwind the scope chain within the exception handler's call frame.
710     int targetScopeDepth = handler->scopeDepth;
711     if (codeBlock->needsActivation() && callFrame->hasActivation())
712         ++targetScopeDepth;
713
714     int scopeRegisterOffset = codeBlock->scopeRegister().offset();
715     JSScope* scope = callFrame->scope(scopeRegisterOffset);
716     int scopeDelta = scope->depth() - targetScopeDepth;
717     RELEASE_ASSERT(scopeDelta >= 0);
718
719     while (scopeDelta--)
720         scope = scope->next();
721
722     callFrame->setScope(scopeRegisterOffset, scope);
723
724     return handler;
725 }
726
727 static inline JSValue checkedReturn(JSValue returnValue)
728 {
729     ASSERT(returnValue);
730     return returnValue;
731 }
732
733 static inline JSObject* checkedReturn(JSObject* returnValue)
734 {
735     ASSERT(returnValue);
736     return returnValue;
737 }
738
739 class SamplingScope {
740 public:
741     SamplingScope(Interpreter* interpreter)
742         : m_interpreter(interpreter)
743     {
744         interpreter->startSampling();
745     }
746     ~SamplingScope()
747     {
748         m_interpreter->stopSampling();
749     }
750 private:
751     Interpreter* m_interpreter;
752 };
753
754 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
755 {
756     SamplingScope samplingScope(this);
757
758     JSScope* scope = thisObj->globalObject();
759     VM& vm = *scope->vm();
760
761     ASSERT(!vm.exception());
762     ASSERT(!vm.isCollectorBusy());
763     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
764     if (vm.isCollectorBusy())
765         return jsNull();
766
767     if (!vm.isSafeToRecurse())
768         return checkedReturn(throwStackOverflowError(callFrame));
769
770     // First check if the "program" is actually just a JSON object. If so,
771     // we'll handle the JSON object here. Else, we'll handle real JS code
772     // below at failedJSONP.
773
774     Vector<JSONPData> JSONPData;
775     bool parseResult;
776     const String programSource = program->source().toString();
777     if (programSource.isNull())
778         return jsUndefined();
779     if (programSource.is8Bit()) {
780         LiteralParser<LChar> literalParser(callFrame, programSource.characters8(), programSource.length(), JSONP);
781         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
782     } else {
783         LiteralParser<UChar> literalParser(callFrame, programSource.characters16(), programSource.length(), JSONP);
784         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
785     }
786
787     if (parseResult) {
788         JSGlobalObject* globalObject = scope->globalObject();
789         JSValue result;
790         for (unsigned entry = 0; entry < JSONPData.size(); entry++) {
791             Vector<JSONPPathEntry> JSONPPath;
792             JSONPPath.swap(JSONPData[entry].m_path);
793             JSValue JSONPValue = JSONPData[entry].m_value.get();
794             if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
795                 globalObject->addVar(callFrame, JSONPPath[0].m_pathEntryName);
796                 PutPropertySlot slot(globalObject);
797                 globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
798                 result = jsUndefined();
799                 continue;
800             }
801             JSValue baseObject(globalObject);
802             for (unsigned i = 0; i < JSONPPath.size() - 1; i++) {
803                 ASSERT(JSONPPath[i].m_type != JSONPPathEntryTypeDeclare);
804                 switch (JSONPPath[i].m_type) {
805                 case JSONPPathEntryTypeDot: {
806                     if (i == 0) {
807                         PropertySlot slot(globalObject);
808                         if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
809                             if (entry)
810                                 return callFrame->vm().throwException(callFrame, createUndefinedVariableError(callFrame, JSONPPath[i].m_pathEntryName));
811                             goto failedJSONP;
812                         }
813                         baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
814                     } else
815                         baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathEntryName);
816                     if (callFrame->hadException())
817                         return jsUndefined();
818                     continue;
819                 }
820                 case JSONPPathEntryTypeLookup: {
821                     baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathIndex);
822                     if (callFrame->hadException())
823                         return jsUndefined();
824                     continue;
825                 }
826                 default:
827                     RELEASE_ASSERT_NOT_REACHED();
828                     return jsUndefined();
829                 }
830             }
831             PutPropertySlot slot(baseObject);
832             switch (JSONPPath.last().m_type) {
833             case JSONPPathEntryTypeCall: {
834                 JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
835                 if (callFrame->hadException())
836                     return jsUndefined();
837                 CallData callData;
838                 CallType callType = getCallData(function, callData);
839                 if (callType == CallTypeNone)
840                     return callFrame->vm().throwException(callFrame, createNotAFunctionError(callFrame, function));
841                 MarkedArgumentBuffer jsonArg;
842                 jsonArg.append(JSONPValue);
843                 JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
844                 JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
845                 if (callFrame->hadException())
846                     return jsUndefined();
847                 break;
848             }
849             case JSONPPathEntryTypeDot: {
850                 baseObject.put(callFrame, JSONPPath.last().m_pathEntryName, JSONPValue, slot);
851                 if (callFrame->hadException())
852                     return jsUndefined();
853                 break;
854             }
855             case JSONPPathEntryTypeLookup: {
856                 baseObject.putByIndex(callFrame, JSONPPath.last().m_pathIndex, JSONPValue, slot.isStrictMode());
857                 if (callFrame->hadException())
858                     return jsUndefined();
859                 break;
860             }
861             default:
862                 RELEASE_ASSERT_NOT_REACHED();
863                     return jsUndefined();
864             }
865             result = JSONPValue;
866         }
867         return result;
868     }
869 failedJSONP:
870     // If we get here, then we have already proven that the script is not a JSON
871     // object.
872
873     VMEntryScope entryScope(vm, scope->globalObject());
874
875     // Compile source to bytecode if necessary:
876     if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
877         return checkedReturn(callFrame->vm().throwException(callFrame, error));
878
879     if (JSObject* error = program->prepareForExecution(callFrame, nullptr, scope, CodeForCall))
880         return checkedReturn(callFrame->vm().throwException(callFrame, error));
881
882     ProgramCodeBlock* codeBlock = program->codeBlock();
883
884     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
885         return throwTerminatedExecutionException(callFrame);
886
887     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
888
889     ProtoCallFrame protoCallFrame;
890     protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), thisObj, 1);
891
892     if (LegacyProfiler* profiler = vm.enabledProfiler())
893         profiler->willExecute(callFrame, program->sourceURL(), program->firstLine(), program->startColumn());
894
895     // Execute the code:
896     JSValue result;
897     {
898         SamplingTool::CallRecord callRecord(m_sampler.get());
899         Watchdog::Scope watchdogScope(vm.watchdog.get());
900
901         result = program->generatedJITCode()->execute(&vm, &protoCallFrame);
902     }
903
904     if (LegacyProfiler* profiler = vm.enabledProfiler())
905         profiler->didExecute(callFrame, program->sourceURL(), program->firstLine(), program->startColumn());
906
907     return checkedReturn(result);
908 }
909
910 JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
911 {
912     VM& vm = callFrame->vm();
913     ASSERT(!callFrame->hadException());
914     ASSERT(!vm.isCollectorBusy());
915     if (vm.isCollectorBusy())
916         return jsNull();
917
918     bool isJSCall = (callType == CallTypeJS);
919     JSScope* scope = nullptr;
920     CodeBlock* newCodeBlock;
921     size_t argsCount = 1 + args.size(); // implicit "this" parameter
922
923     JSGlobalObject* globalObject;
924
925     if (isJSCall) {
926         scope = callData.js.scope;
927         globalObject = scope->globalObject();
928     } else {
929         ASSERT(callType == CallTypeHost);
930         globalObject = function->globalObject();
931     }
932
933     VMEntryScope entryScope(vm, globalObject);
934     if (!vm.isSafeToRecurse())
935         return checkedReturn(throwStackOverflowError(callFrame));
936
937     if (isJSCall) {
938         // Compile the callee:
939         JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(function), scope, CodeForCall);
940         if (UNLIKELY(!!compileError)) {
941             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
942         }
943         newCodeBlock = callData.js.functionExecutable->codeBlockForCall();
944         ASSERT(!!newCodeBlock);
945         newCodeBlock->m_shouldAlwaysBeInlined = false;
946     } else
947         newCodeBlock = 0;
948
949     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
950         return throwTerminatedExecutionException(callFrame);
951
952     ProtoCallFrame protoCallFrame;
953     protoCallFrame.init(newCodeBlock, function, thisValue, argsCount, args.data());
954
955     if (LegacyProfiler* profiler = vm.enabledProfiler())
956         profiler->willExecute(callFrame, function);
957
958     JSValue result;
959     {
960         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
961         Watchdog::Scope watchdogScope(vm.watchdog.get());
962
963         // Execute the code:
964         if (isJSCall)
965             result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame);
966         else {
967             result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));
968             if (callFrame->hadException())
969                 result = jsNull();
970         }
971     }
972
973     if (LegacyProfiler* profiler = vm.enabledProfiler())
974         profiler->didExecute(callFrame, function);
975
976     return checkedReturn(result);
977 }
978
979 JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
980 {
981     VM& vm = callFrame->vm();
982     ASSERT(!callFrame->hadException());
983     ASSERT(!vm.isCollectorBusy());
984     // We throw in this case because we have to return something "valid" but we're
985     // already in an invalid state.
986     if (vm.isCollectorBusy())
987         return checkedReturn(throwStackOverflowError(callFrame));
988
989     bool isJSConstruct = (constructType == ConstructTypeJS);
990     JSScope* scope = nullptr;
991     CodeBlock* newCodeBlock;
992     size_t argsCount = 1 + args.size(); // implicit "this" parameter
993
994     JSGlobalObject* globalObject;
995
996     if (isJSConstruct) {
997         scope = constructData.js.scope;
998         globalObject = scope->globalObject();
999     } else {
1000         ASSERT(constructType == ConstructTypeHost);
1001         globalObject = constructor->globalObject();
1002     }
1003
1004     VMEntryScope entryScope(vm, globalObject);
1005     if (!vm.isSafeToRecurse())
1006         return checkedReturn(throwStackOverflowError(callFrame));
1007
1008     if (isJSConstruct) {
1009         // Compile the callee:
1010         JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(constructor), scope, CodeForConstruct);
1011         if (UNLIKELY(!!compileError)) {
1012             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1013         }
1014         newCodeBlock = constructData.js.functionExecutable->codeBlockForConstruct();
1015         ASSERT(!!newCodeBlock);
1016         newCodeBlock->m_shouldAlwaysBeInlined = false;
1017     } else
1018         newCodeBlock = 0;
1019
1020     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
1021         return throwTerminatedExecutionException(callFrame);
1022
1023     ProtoCallFrame protoCallFrame;
1024     protoCallFrame.init(newCodeBlock, constructor, constructor, argsCount, args.data());
1025
1026     if (LegacyProfiler* profiler = vm.enabledProfiler())
1027         profiler->willExecute(callFrame, constructor);
1028
1029     JSValue result;
1030     {
1031         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
1032         Watchdog::Scope watchdogScope(vm.watchdog.get());
1033
1034         // Execute the code.
1035         if (isJSConstruct)
1036             result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame);
1037         else {
1038             result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));
1039
1040             if (!callFrame->hadException())
1041                 RELEASE_ASSERT(result.isObject());
1042         }
1043     }
1044
1045     if (LegacyProfiler* profiler = vm.enabledProfiler())
1046         profiler->didExecute(callFrame, constructor);
1047
1048     if (callFrame->hadException())
1049         return 0;
1050     ASSERT(result.isObject());
1051     return checkedReturn(asObject(result));
1052 }
1053
1054 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
1055 {
1056     VM& vm = *scope->vm();
1057     ASSERT(!vm.exception());
1058     
1059     if (vm.isCollectorBusy())
1060         return CallFrameClosure();
1061
1062     // Compile the callee:
1063     JSObject* error = functionExecutable->prepareForExecution(callFrame, function, scope, CodeForCall);
1064     if (error) {
1065         callFrame->vm().throwException(callFrame, error);
1066         return CallFrameClosure();
1067     }
1068     CodeBlock* newCodeBlock = functionExecutable->codeBlockForCall();
1069     newCodeBlock->m_shouldAlwaysBeInlined = false;
1070
1071     size_t argsCount = argumentCountIncludingThis;
1072
1073     protoCallFrame->init(newCodeBlock, function, jsUndefined(), argsCount, args);
1074     // Return the successful closure:
1075     CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
1076     return result;
1077 }
1078
1079 JSValue Interpreter::execute(CallFrameClosure& closure) 
1080 {
1081     VM& vm = *closure.vm;
1082     SamplingScope samplingScope(this);
1083     
1084     ASSERT(!vm.isCollectorBusy());
1085     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
1086     if (vm.isCollectorBusy())
1087         return jsNull();
1088
1089     StackStats::CheckPoint stackCheckPoint;
1090
1091     if (LegacyProfiler* profiler = vm.enabledProfiler())
1092         profiler->willExecute(closure.oldCallFrame, closure.function);
1093
1094     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(closure.oldCallFrame)))
1095         return throwTerminatedExecutionException(closure.oldCallFrame);
1096
1097     // Execute the code:
1098     JSValue result;
1099     {
1100         SamplingTool::CallRecord callRecord(m_sampler.get());
1101         Watchdog::Scope watchdogScope(vm.watchdog.get());
1102
1103         result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.protoCallFrame);
1104     }
1105
1106     if (LegacyProfiler* profiler = vm.enabledProfiler())
1107         profiler->didExecute(closure.oldCallFrame, closure.function);
1108
1109     return checkedReturn(result);
1110 }
1111
1112 JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
1113 {
1114     VM& vm = *scope->vm();
1115     SamplingScope samplingScope(this);
1116     
1117     ASSERT(scope->vm() == &callFrame->vm());
1118     ASSERT(!vm.exception());
1119     ASSERT(!vm.isCollectorBusy());
1120     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
1121     if (vm.isCollectorBusy())
1122         return jsNull();
1123
1124     VMEntryScope entryScope(vm, scope->globalObject());
1125     if (!vm.isSafeToRecurse())
1126         return checkedReturn(throwStackOverflowError(callFrame));        
1127
1128     unsigned numVariables = eval->numVariables();
1129     int numFunctions = eval->numberOfFunctionDecls();
1130
1131     JSScope* variableObject;
1132     if ((numVariables || numFunctions) && eval->isStrictMode()) {
1133         scope = StrictEvalActivation::create(callFrame, scope);
1134         variableObject = scope;
1135     } else {
1136         for (JSScope* node = scope; ; node = node->next()) {
1137             RELEASE_ASSERT(node);
1138             if (node->isGlobalObject()) {
1139                 variableObject = node;
1140                 break;
1141             } 
1142             if (JSLexicalEnvironment* lexicalEnvironment = jsDynamicCast<JSLexicalEnvironment*>(node)) {
1143                 if (!lexicalEnvironment->symbolTable()->correspondsToLexicalScope()) {
1144                     variableObject = node;
1145                     break;
1146                 }
1147             }
1148         }
1149         ASSERT(!variableObject->isNameScopeObject());
1150     }
1151
1152     JSObject* compileError = eval->prepareForExecution(callFrame, nullptr, scope, CodeForCall);
1153     if (UNLIKELY(!!compileError))
1154         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1155     EvalCodeBlock* codeBlock = eval->codeBlock();
1156
1157     if (numVariables || numFunctions) {
1158         BatchedTransitionOptimizer optimizer(vm, variableObject);
1159         if (variableObject->next())
1160             variableObject->globalObject()->varInjectionWatchpoint()->fireAll("Executed eval, fired VarInjection watchpoint");
1161
1162         for (unsigned i = 0; i < numVariables; ++i) {
1163             const Identifier& ident = codeBlock->variable(i);
1164             if (!variableObject->hasProperty(callFrame, ident)) {
1165                 PutPropertySlot slot(variableObject);
1166                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
1167             }
1168         }
1169
1170         for (int i = 0; i < numFunctions; ++i) {
1171             FunctionExecutable* function = codeBlock->functionDecl(i);
1172             PutPropertySlot slot(variableObject);
1173             variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
1174         }
1175     }
1176
1177     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
1178         return throwTerminatedExecutionException(callFrame);
1179
1180     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1181
1182     ProtoCallFrame protoCallFrame;
1183     protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), thisValue, 1);
1184
1185     if (LegacyProfiler* profiler = vm.enabledProfiler())
1186         profiler->willExecute(callFrame, eval->sourceURL(), eval->firstLine(), eval->startColumn());
1187
1188     // Execute the code:
1189     JSValue result;
1190     {
1191         SamplingTool::CallRecord callRecord(m_sampler.get());
1192         Watchdog::Scope watchdogScope(vm.watchdog.get());
1193
1194         result = eval->generatedJITCode()->execute(&vm, &protoCallFrame);
1195     }
1196
1197     if (LegacyProfiler* profiler = vm.enabledProfiler())
1198         profiler->didExecute(callFrame, eval->sourceURL(), eval->firstLine(), eval->startColumn());
1199
1200     return checkedReturn(result);
1201 }
1202
1203 NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID)
1204 {
1205     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
1206     if (!debugger)
1207         return;
1208
1209     ASSERT(callFrame->codeBlock()->hasDebuggerRequests());
1210     ASSERT(!callFrame->hadException());
1211
1212     switch (debugHookID) {
1213         case DidEnterCallFrame:
1214             debugger->callEvent(callFrame);
1215             break;
1216         case WillLeaveCallFrame:
1217             debugger->returnEvent(callFrame);
1218             break;
1219         case WillExecuteStatement:
1220             debugger->atStatement(callFrame);
1221             break;
1222         case WillExecuteProgram:
1223             debugger->willExecuteProgram(callFrame);
1224             break;
1225         case DidExecuteProgram:
1226             debugger->didExecuteProgram(callFrame);
1227             break;
1228         case DidReachBreakpoint:
1229             debugger->didReachBreakpoint(callFrame);
1230             break;
1231     }
1232     ASSERT(!callFrame->hadException());
1233 }    
1234
1235 void Interpreter::enableSampler()
1236 {
1237 #if ENABLE(OPCODE_SAMPLING)
1238     if (!m_sampler) {
1239         m_sampler = std::make_unique<SamplingTool>(this);
1240         m_sampler->setup();
1241     }
1242 #endif
1243 }
1244 void Interpreter::dumpSampleData(ExecState* exec)
1245 {
1246 #if ENABLE(OPCODE_SAMPLING)
1247     if (m_sampler)
1248         m_sampler->dump(exec);
1249 #else
1250     UNUSED_PARAM(exec);
1251 #endif
1252 }
1253 void Interpreter::startSampling()
1254 {
1255 #if ENABLE(SAMPLING_THREAD)
1256     if (!m_sampleEntryDepth)
1257         SamplingThread::start();
1258
1259     m_sampleEntryDepth++;
1260 #endif
1261 }
1262 void Interpreter::stopSampling()
1263 {
1264 #if ENABLE(SAMPLING_THREAD)
1265     m_sampleEntryDepth--;
1266     if (!m_sampleEntryDepth)
1267         SamplingThread::stop();
1268 #endif
1269 }
1270
1271 } // namespace JSC