Avoid eagerly creating the JSActivation when the debugger is attached.
[WebKit-https.git] / Source / JavaScriptCore / interpreter / Interpreter.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "Interpreter.h"
32
33 #include "Arguments.h"
34 #include "BatchedTransitionOptimizer.h"
35 #include "CallFrameClosure.h"
36 #include "CallFrameInlines.h"
37 #include "CodeBlock.h"
38 #include "Heap.h"
39 #include "Debugger.h"
40 #include "DebuggerCallFrame.h"
41 #include "ErrorInstance.h"
42 #include "EvalCodeCache.h"
43 #include "ExceptionHelpers.h"
44 #include "GetterSetter.h"
45 #include "JSActivation.h"
46 #include "JSArray.h"
47 #include "JSBoundFunction.h"
48 #include "JSNameScope.h"
49 #include "JSNotAnObject.h"
50 #include "JSPropertyNameIterator.h"
51 #include "JSStackInlines.h"
52 #include "JSString.h"
53 #include "JSStringInlines.h"
54 #include "JSWithScope.h"
55 #include "LLIntCLoop.h"
56 #include "LLIntThunks.h"
57 #include "LegacyProfiler.h"
58 #include "LiteralParser.h"
59 #include "NameInstance.h"
60 #include "ObjectPrototype.h"
61 #include "Operations.h"
62 #include "Parser.h"
63 #include "ProtoCallFrame.h"
64 #include "RegExpObject.h"
65 #include "RegExpPrototype.h"
66 #include "Register.h"
67 #include "SamplingTool.h"
68 #include "StackAlignment.h"
69 #include "StackVisitor.h"
70 #include "StrictEvalActivation.h"
71 #include "StrongInlines.h"
72 #include "VMEntryScope.h"
73 #include "VirtualRegister.h"
74
75 #include <limits.h>
76 #include <stdio.h>
77 #include <wtf/StackStats.h>
78 #include <wtf/StdLibExtras.h>
79 #include <wtf/StringPrintStream.h>
80 #include <wtf/Threading.h>
81 #include <wtf/WTFThreadData.h>
82 #include <wtf/text/StringBuilder.h>
83
84 #if ENABLE(JIT)
85 #include "JIT.h"
86 #endif
87
88 #define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(LLINT) && !defined(__llvm__))
89
90 using namespace std;
91
92 namespace JSC {
93
94 JSValue eval(CallFrame* callFrame)
95 {
96     if (!callFrame->argumentCount())
97         return jsUndefined();
98
99     JSValue program = callFrame->argument(0);
100     if (!program.isString())
101         return program;
102     
103     TopCallFrameSetter topCallFrame(callFrame->vm(), callFrame);
104     String programSource = asString(program)->value(callFrame);
105     if (callFrame->hadException())
106         return JSValue();
107     
108     CallFrame* callerFrame = callFrame->callerFrame();
109     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
110     JSScope* callerScopeChain = callerFrame->scope();
111     EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
112
113     if (!eval) {
114         if (!callerCodeBlock->isStrictMode()) {
115             // FIXME: We can use the preparser in strict mode, we just need additional logic
116             // to prevent duplicates.
117             if (programSource.is8Bit()) {
118                 LiteralParser<LChar> preparser(callFrame, programSource.characters8(), programSource.length(), NonStrictJSON);
119                 if (JSValue parsedObject = preparser.tryLiteralParse())
120                     return parsedObject;
121             } else {
122                 LiteralParser<UChar> preparser(callFrame, programSource.characters16(), programSource.length(), NonStrictJSON);
123                 if (JSValue parsedObject = preparser.tryLiteralParse())
124                     return parsedObject;                
125             }
126         }
127         
128         // If the literal parser bailed, it should not have thrown exceptions.
129         ASSERT(!callFrame->vm().exception());
130
131         eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
132         if (!eval)
133             return jsUndefined();
134     }
135
136     JSValue thisValue = callerFrame->thisValue();
137     Interpreter* interpreter = callFrame->vm().interpreter;
138     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
139 }
140
141 CallFrame* sizeFrameForVarargs(CallFrame* callFrame, JSStack* stack, JSValue arguments, int firstFreeRegister)
142 {
143     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
144         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
145         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
146         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
147         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->ensureCapacityFor(newCallFrame->registers())) {
148             throwStackOverflowError(callFrame);
149             return 0;
150         }
151         return newCallFrame;
152     }
153
154     if (arguments.isUndefinedOrNull()) {
155         unsigned argumentCountIncludingThis = 1;
156         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(),  -firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize + 1);
157         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
158         if (!stack->ensureCapacityFor(newCallFrame->registers())) {
159             throwStackOverflowError(callFrame);
160             return 0;
161         }
162         return newCallFrame;
163     }
164
165     if (!arguments.isObject()) {
166         callFrame->vm().throwException(callFrame, createInvalidParameterError(callFrame, "Function.prototype.apply", arguments));
167         return 0;
168     }
169
170     if (asObject(arguments)->classInfo() == Arguments::info()) {
171         Arguments* argsObject = asArguments(arguments);
172         unsigned argCount = argsObject->length(callFrame);
173         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
174         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
175         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
176             throwStackOverflowError(callFrame);
177             return 0;
178         }
179         return newCallFrame;
180     }
181
182     if (isJSArray(arguments)) {
183         JSArray* array = asArray(arguments);
184         unsigned argCount = array->length();
185         unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
186         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
187         if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
188             throwStackOverflowError(callFrame);
189             return 0;
190         }
191         return newCallFrame;
192     }
193
194     JSObject* argObject = asObject(arguments);
195     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
196     unsigned paddedCalleeFrameOffset = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister + CallFrame::offsetFor(argCount + 1));
197     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() - paddedCalleeFrameOffset);
198     if (argCount > Arguments::MaxArguments || !stack->ensureCapacityFor(newCallFrame->registers())) {
199         throwStackOverflowError(callFrame);
200         return 0;
201     }
202     return newCallFrame;
203 }
204
205 void loadVarargs(CallFrame* callFrame, CallFrame* newCallFrame, JSValue thisValue, JSValue arguments)
206 {
207     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
208         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
209
210         newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
211         newCallFrame->setThisValue(thisValue);
212         for (size_t i = 0; i < callFrame->argumentCount(); ++i)
213             newCallFrame->setArgument(i, callFrame->argumentAfterCapture(i));
214         return;
215     }
216     
217     if (arguments.isUndefinedOrNull()) {
218         newCallFrame->setArgumentCountIncludingThis(1);
219         newCallFrame->setThisValue(thisValue);
220         return;
221     }
222     
223     if (asObject(arguments)->classInfo() == Arguments::info()) {
224         Arguments* argsObject = asArguments(arguments);
225         unsigned argCount = argsObject->length(callFrame);
226         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
227         newCallFrame->setThisValue(thisValue);
228         argsObject->copyToArguments(callFrame, newCallFrame, argCount);
229         return;
230     }
231     
232     if (isJSArray(arguments)) {
233         JSArray* array = asArray(arguments);
234         unsigned argCount = array->length();
235         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
236         newCallFrame->setThisValue(thisValue);
237         array->copyToArguments(callFrame, newCallFrame, argCount);
238         return;
239     }
240     
241     JSObject* argObject = asObject(arguments);
242     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
243     newCallFrame->setArgumentCountIncludingThis(argCount + 1);
244     newCallFrame->setThisValue(thisValue);
245     for (size_t i = 0; i < argCount; ++i) {
246         newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i));
247         if (UNLIKELY(callFrame->vm().exception()))
248             return;
249     }
250 }
251
252 Interpreter::Interpreter(VM& vm)
253     : m_sampleEntryDepth(0)
254     , m_vm(vm)
255     , m_stack(vm)
256     , m_errorHandlingModeReentry(0)
257 #if !ASSERT_DISABLED
258     , m_initialized(false)
259 #endif
260 {
261 }
262
263 Interpreter::~Interpreter()
264 {
265 }
266
267 void Interpreter::initialize(bool canUseJIT)
268 {
269     UNUSED_PARAM(canUseJIT);
270
271 #if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
272     m_opcodeTable = LLInt::opcodeMap();
273     for (int i = 0; i < numOpcodeIDs; ++i)
274         m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
275 #endif
276
277 #if !ASSERT_DISABLED
278     m_initialized = true;
279 #endif
280
281 #if ENABLE(OPCODE_SAMPLING)
282     enableSampler();
283 #endif
284 }
285
286 #ifdef NDEBUG
287
288 void Interpreter::dumpCallFrame(CallFrame*)
289 {
290 }
291
292 #else
293
294 void Interpreter::dumpCallFrame(CallFrame* callFrame)
295 {
296     callFrame->codeBlock()->dumpBytecode();
297     dumpRegisters(callFrame);
298 }
299
300 class DumpRegisterFunctor {
301 public:
302     DumpRegisterFunctor(const Register*& it)
303         : m_hasSkippedFirstFrame(false)
304         , m_it(it)
305     {
306     }
307
308     StackVisitor::Status operator()(StackVisitor& visitor)
309     {
310         if (!m_hasSkippedFirstFrame) {
311             m_hasSkippedFirstFrame = true;
312             return StackVisitor::Continue;
313         }
314
315         unsigned line = 0;
316         unsigned unusedColumn = 0;
317         visitor->computeLineAndColumn(line, unusedColumn);
318         dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", m_it, visitor->bytecodeOffset(), line);
319         --m_it;
320         return StackVisitor::Done;
321     }
322
323 private:
324     bool m_hasSkippedFirstFrame;
325     const Register*& m_it;
326 };
327
328 void Interpreter::dumpRegisters(CallFrame* callFrame)
329 {
330     dataLogF("Register frame: \n\n");
331     dataLogF("-----------------------------------------------------------------------------\n");
332     dataLogF("            use            |   address  |                value               \n");
333     dataLogF("-----------------------------------------------------------------------------\n");
334
335     CodeBlock* codeBlock = callFrame->codeBlock();
336     const Register* it;
337     const Register* end;
338
339     it = callFrame->registers() + JSStack::ThisArgument + callFrame->argumentCount();
340     end = callFrame->registers() + JSStack::ThisArgument - 1;
341     while (it > end) {
342         JSValue v = it->jsValue();
343         int registerNumber = it - callFrame->registers();
344         String name = codeBlock->nameForRegister(VirtualRegister(registerNumber));
345         dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
346         --it;
347     }
348     
349     dataLogF("-----------------------------------------------------------------------------\n");
350     dataLogF("[ArgumentCount]            | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount());
351     --it;
352     dataLogF("[CallerFrame]              | %10p | %p \n", it, callFrame->callerFrame());
353     --it;
354     dataLogF("[Callee]                   | %10p | %p \n", it, callFrame->callee());
355     --it;
356     dataLogF("[ScopeChain]               | %10p | %p \n", it, callFrame->scope());
357     --it;
358 #if ENABLE(JIT)
359     AbstractPC pc = callFrame->abstractReturnPC(callFrame->vm());
360     if (pc.hasJITReturnAddress())
361         dataLogF("[ReturnJITPC]              | %10p | %p \n", it, pc.jitReturnAddress().value());
362 #endif
363
364     DumpRegisterFunctor functor(it);
365     callFrame->iterate(functor);
366
367     dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
368     --it;
369     dataLogF("-----------------------------------------------------------------------------\n");
370
371     end = it - codeBlock->m_numVars;
372     if (it != end) {
373         do {
374             JSValue v = it->jsValue();
375             int registerNumber = it - callFrame->registers();
376             String name = codeBlock->nameForRegister(VirtualRegister(registerNumber));
377             dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, toCString(v).data(), (long long)JSValue::encode(v));
378             --it;
379         } while (it != end);
380     }
381     dataLogF("-----------------------------------------------------------------------------\n");
382
383     end = it - codeBlock->m_numCalleeRegisters + codeBlock->m_numVars;
384     if (it != end) {
385         do {
386             JSValue v = (*it).jsValue();
387             int registerNumber = it - callFrame->registers();
388             dataLogF("[r% 3d]                     | %10p | %-16s 0x%lld \n", registerNumber, it, toCString(v).data(), (long long)JSValue::encode(v));
389             --it;
390         } while (it != end);
391     }
392     dataLogF("-----------------------------------------------------------------------------\n");
393 }
394
395 #endif
396
397 bool Interpreter::isOpcode(Opcode opcode)
398 {
399 #if ENABLE(COMPUTED_GOTO_OPCODES)
400 #if !ENABLE(LLINT)
401     return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
402 #else
403     return opcode != HashTraits<Opcode>::emptyValue()
404         && !HashTraits<Opcode>::isDeletedValue(opcode)
405         && m_opcodeIDTable.contains(opcode);
406 #endif
407 #else
408     return opcode >= 0 && opcode <= op_end;
409 #endif
410 }
411
412 static bool unwindCallFrame(StackVisitor& visitor)
413 {
414     CallFrame* callFrame = visitor->callFrame();
415     CodeBlock* codeBlock = visitor->codeBlock();
416     JSScope* scope = callFrame->scope();
417
418     if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) {
419         if (callFrame->callee())
420             debugger->returnEvent(callFrame);
421         else
422             debugger->didExecuteProgram(callFrame);
423     }
424
425     JSValue activation;
426     if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
427 #if ENABLE(DFG_JIT)
428         RELEASE_ASSERT(!visitor->isInlinedFrame());
429 #endif
430         activation = callFrame->uncheckedActivation();
431         if (activation)
432             jsCast<JSActivation*>(activation)->tearOff(*scope->vm());
433     }
434
435     if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
436         if (Arguments* arguments = visitor->existingArguments()) {
437             if (activation)
438                 arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
439 #if ENABLE(DFG_JIT)
440             else if (visitor->isInlinedFrame())
441                 arguments->tearOff(callFrame, visitor->inlineCallFrame());
442 #endif
443             else
444                 arguments->tearOff(callFrame);
445         }
446     }
447
448     CallFrame* callerFrame = callFrame->callerFrame();
449     return !callerFrame->isVMEntrySentinel();
450 }
451
452 static StackFrameCodeType getStackFrameCodeType(StackVisitor& visitor)
453 {
454     switch (visitor->codeType()) {
455     case StackVisitor::Frame::Eval:
456         return StackFrameEvalCode;
457     case StackVisitor::Frame::Function:
458         return StackFrameFunctionCode;
459     case StackVisitor::Frame::Global:
460         return StackFrameGlobalCode;
461     case StackVisitor::Frame::Native:
462         ASSERT_NOT_REACHED();
463         return StackFrameNativeCode;
464     }
465     RELEASE_ASSERT_NOT_REACHED();
466     return StackFrameGlobalCode;
467 }
468
469 void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column)
470 {
471     if (!codeBlock) {
472         line = 0;
473         column = 0;
474         return;
475     }
476
477     int divot = 0;
478     int unusedStartOffset = 0;
479     int unusedEndOffset = 0;
480     unsigned divotLine = 0;
481     unsigned divotColumn = 0;
482     expressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
483
484     line = divotLine + lineOffset;
485     column = divotColumn + (divotLine ? 1 : firstLineColumnOffset);
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()) {
532                 CodeBlock* codeBlock = visitor->codeBlock();
533                 StackFrame s = {
534                     Strong<JSObject>(vm, visitor->callee()),
535                     getStackFrameCodeType(visitor),
536                     Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()),
537                     Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
538                     codeBlock->source(),
539                     codeBlock->ownerExecutable()->lineNo(),
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<ExecutableBase>(), 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     ASSERT(!vm.topCallFrame->isVMEntrySentinel());
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 GetExceptionHandlerFunctor {
588 public:
589     GetExceptionHandlerFunctor()
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);
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(CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
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_callFrame = visitor->callFrame();
628         m_codeBlock = visitor->codeBlock();
629         unsigned bytecodeOffset = visitor->bytecodeOffset();
630
631         if (m_isTermination || !(m_handler = m_codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
632             if (!unwindCallFrame(visitor)) {
633                 if (LegacyProfiler* profiler = vm.enabledProfiler())
634                     profiler->exceptionUnwind(m_callFrame);
635                 return StackVisitor::Done;
636             }
637         } else
638             return StackVisitor::Done;
639
640         return StackVisitor::Continue;
641     }
642
643 private:
644     CallFrame*& m_callFrame;
645     bool m_isTermination;
646     CodeBlock*& m_codeBlock;
647     HandlerInfo*& m_handler;
648 };
649
650 NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& exceptionValue)
651 {
652     if (callFrame->isVMEntrySentinel()) {
653         // This happens when we throw stack overflow in a function that is called
654         // directly from callToJavaScript. Stack overflow throws the exception in the
655         // context of the caller. In that case the caller is the sentinel frame. The
656         // right thing to do is to pretend that the exception is uncaught so that we
657         // go to the uncaught exception handler, which returns through callToJavaScript.
658         return 0;
659     }
660     
661     CodeBlock* codeBlock = callFrame->codeBlock();
662     ASSERT(codeBlock);
663     bool isTermination = false;
664
665     ASSERT(!exceptionValue.isEmpty());
666     ASSERT(!exceptionValue.isCell() || exceptionValue.asCell());
667     // This shouldn't be possible (hence the assertions), but we're already in the slowest of
668     // slow cases, so let's harden against it anyway to be safe.
669     if (exceptionValue.isEmpty() || (exceptionValue.isCell() && !exceptionValue.asCell()))
670         exceptionValue = jsNull();
671
672     if (exceptionValue.isObject()) {
673         isTermination = isTerminatedExecutionException(asObject(exceptionValue));
674     }
675
676     ASSERT(callFrame->vm().exceptionStack().size());
677
678     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
679     if (debugger && debugger->needsExceptionCallbacks()) {
680         // We need to clear the exception and the exception stack here in order to see if a new exception happens.
681         // Afterwards, the values are put back to continue processing this error.
682         ClearExceptionScope scope(&callFrame->vm());
683         // This code assumes that if the debugger is enabled then there is no inlining.
684         // If that assumption turns out to be false then we'll ignore the inlined call
685         // frames.
686         // https://bugs.webkit.org/show_bug.cgi?id=121754
687
688         bool hasHandler;
689         if (isTermination)
690             hasHandler = false;
691         else {
692             GetExceptionHandlerFunctor functor;
693             callFrame->iterate(functor);
694             hasHandler = !!functor.handler();
695         }
696
697         debugger->exception(callFrame, exceptionValue, hasHandler);
698     }
699
700     // Calculate an exception handler vPC, unwinding call frames as necessary.
701     HandlerInfo* handler = 0;
702     VM& vm = callFrame->vm();
703     ASSERT(callFrame == vm.topCallFrame);
704     UnwindFunctor functor(callFrame, isTermination, codeBlock, handler);
705     callFrame->iterate(functor);
706     if (!handler)
707         return 0;
708
709     if (LegacyProfiler* profiler = vm.enabledProfiler())
710         profiler->exceptionUnwind(callFrame);
711
712     // Unwind the scope chain within the exception handler's call frame.
713     int targetScopeDepth = handler->scopeDepth;
714     if (codeBlock->needsActivation() && callFrame->hasActivation())
715         ++targetScopeDepth;
716
717     JSScope* scope = callFrame->scope();
718     int scopeDelta = scope->depth() - targetScopeDepth;
719     RELEASE_ASSERT(scopeDelta >= 0);
720
721     while (scopeDelta--)
722         scope = scope->next();
723     callFrame->setScope(scope);
724
725     return handler;
726 }
727
728 static inline JSValue checkedReturn(JSValue returnValue)
729 {
730     ASSERT(returnValue);
731     return returnValue;
732 }
733
734 static inline JSObject* checkedReturn(JSObject* returnValue)
735 {
736     ASSERT(returnValue);
737     return returnValue;
738 }
739
740 class SamplingScope {
741 public:
742     SamplingScope(Interpreter* interpreter)
743         : m_interpreter(interpreter)
744     {
745         interpreter->startSampling();
746     }
747     ~SamplingScope()
748     {
749         m_interpreter->stopSampling();
750     }
751 private:
752     Interpreter* m_interpreter;
753 };
754
755 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
756 {
757     SamplingScope samplingScope(this);
758     
759     JSScope* scope = callFrame->scope();
760     VM& vm = *scope->vm();
761
762     ASSERT(!vm.exception());
763     ASSERT(!vm.isCollectorBusy());
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(globalObject->globalExec(), 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, scope, CodeForCall))
880         return checkedReturn(callFrame->vm().throwException(callFrame, error));
881
882     ProgramCodeBlock* codeBlock = program->codeBlock();
883
884     if (UNLIKELY(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, scope, 0, thisObj, 1);
891
892     if (LegacyProfiler* profiler = vm.enabledProfiler())
893         profiler->willExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
894
895     // Execute the code:
896     JSValue result;
897     {
898         SamplingTool::CallRecord callRecord(m_sampler.get());
899         Watchdog::Scope watchdogScope(vm.watchdog);
900
901         result = program->generatedJITCode()->execute(&vm, &protoCallFrame);
902     }
903
904     if (LegacyProfiler* profiler = vm.enabledProfiler())
905         profiler->didExecute(callFrame, program->sourceURL(), program->lineNo(), 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;
920     CodeBlock* newCodeBlock;
921     size_t argsCount = 1 + args.size(); // implicit "this" parameter
922
923     if (isJSCall)
924         scope = callData.js.scope;
925     else {
926         ASSERT(callType == CallTypeHost);
927         scope = callFrame->scope();
928     }
929
930     VMEntryScope entryScope(vm, scope->globalObject());
931     if (!vm.isSafeToRecurse())
932         return checkedReturn(throwStackOverflowError(callFrame));
933
934     if (isJSCall) {
935         // Compile the callee:
936         JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
937         if (UNLIKELY(!!compileError)) {
938             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
939         }
940         newCodeBlock = callData.js.functionExecutable->codeBlockForCall();
941         ASSERT(!!newCodeBlock);
942         newCodeBlock->m_shouldAlwaysBeInlined = false;
943     } else
944         newCodeBlock = 0;
945
946     if (UNLIKELY(vm.watchdog.didFire(callFrame)))
947         return throwTerminatedExecutionException(callFrame);
948
949     ProtoCallFrame protoCallFrame;
950     protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
951
952     if (LegacyProfiler* profiler = vm.enabledProfiler())
953         profiler->willExecute(callFrame, function);
954
955     JSValue result;
956     {
957         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
958         Watchdog::Scope watchdogScope(vm.watchdog);
959
960         // Execute the code:
961         if (isJSCall)
962             result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame);
963         else {
964             result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));
965             if (callFrame->hadException())
966                 result = jsNull();
967         }
968     }
969
970     if (LegacyProfiler* profiler = vm.enabledProfiler())
971         profiler->didExecute(callFrame, function);
972
973     return checkedReturn(result);
974 }
975
976 JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
977 {
978     VM& vm = callFrame->vm();
979     ASSERT(!callFrame->hadException());
980     ASSERT(!vm.isCollectorBusy());
981     // We throw in this case because we have to return something "valid" but we're
982     // already in an invalid state.
983     if (vm.isCollectorBusy())
984         return checkedReturn(throwStackOverflowError(callFrame));
985
986     bool isJSConstruct = (constructType == ConstructTypeJS);
987     JSScope* scope;
988     CodeBlock* newCodeBlock;
989     size_t argsCount = 1 + args.size(); // implicit "this" parameter
990
991     if (isJSConstruct)
992         scope = constructData.js.scope;
993     else {
994         ASSERT(constructType == ConstructTypeHost);
995         scope = callFrame->scope();
996     }
997
998     VMEntryScope entryScope(vm, scope->globalObject());
999     if (!vm.isSafeToRecurse())
1000         return checkedReturn(throwStackOverflowError(callFrame));
1001
1002     if (isJSConstruct) {
1003         // Compile the callee:
1004         JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, scope, CodeForConstruct);
1005         if (UNLIKELY(!!compileError)) {
1006             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1007         }
1008         newCodeBlock = constructData.js.functionExecutable->codeBlockForConstruct();
1009         ASSERT(!!newCodeBlock);
1010         newCodeBlock->m_shouldAlwaysBeInlined = false;
1011     } else
1012         newCodeBlock = 0;
1013
1014     if (UNLIKELY(vm.watchdog.didFire(callFrame)))
1015         return throwTerminatedExecutionException(callFrame);
1016
1017     ProtoCallFrame protoCallFrame;
1018     protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
1019
1020     if (LegacyProfiler* profiler = vm.enabledProfiler())
1021         profiler->willExecute(callFrame, constructor);
1022
1023     JSValue result;
1024     {
1025         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
1026         Watchdog::Scope watchdogScope(vm.watchdog);
1027
1028         // Execute the code.
1029         if (isJSConstruct)
1030             result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame);
1031         else {
1032             result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));
1033
1034             if (!callFrame->hadException())
1035                 RELEASE_ASSERT(result.isObject());
1036         }
1037     }
1038
1039     if (LegacyProfiler* profiler = vm.enabledProfiler())
1040         profiler->didExecute(callFrame, constructor);
1041
1042     if (callFrame->hadException())
1043         return 0;
1044     ASSERT(result.isObject());
1045     return checkedReturn(asObject(result));
1046 }
1047
1048 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
1049 {
1050     VM& vm = *scope->vm();
1051     ASSERT(!vm.exception());
1052     
1053     if (vm.isCollectorBusy())
1054         return CallFrameClosure();
1055
1056     // Compile the callee:
1057     JSObject* error = functionExecutable->prepareForExecution(callFrame, scope, CodeForCall);
1058     if (error) {
1059         callFrame->vm().throwException(callFrame, error);
1060         return CallFrameClosure();
1061     }
1062     CodeBlock* newCodeBlock = functionExecutable->codeBlockForCall();
1063     newCodeBlock->m_shouldAlwaysBeInlined = false;
1064
1065     size_t argsCount = argumentCountIncludingThis;
1066
1067     protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
1068     // Return the successful closure:
1069     CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
1070     return result;
1071 }
1072
1073 JSValue Interpreter::execute(CallFrameClosure& closure) 
1074 {
1075     VM& vm = *closure.vm;
1076     SamplingScope samplingScope(this);
1077     
1078     ASSERT(!vm.isCollectorBusy());
1079     if (vm.isCollectorBusy())
1080         return jsNull();
1081
1082     StackStats::CheckPoint stackCheckPoint;
1083     closure.resetCallFrame();
1084
1085     if (LegacyProfiler* profiler = vm.enabledProfiler())
1086         profiler->willExecute(closure.oldCallFrame, closure.function);
1087
1088     if (UNLIKELY(vm.watchdog.didFire(closure.oldCallFrame)))
1089         return throwTerminatedExecutionException(closure.oldCallFrame);
1090
1091     // Execute the code:
1092     JSValue result;
1093     {
1094         SamplingTool::CallRecord callRecord(m_sampler.get());
1095         Watchdog::Scope watchdogScope(vm.watchdog);
1096
1097         result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.protoCallFrame);
1098     }
1099
1100     if (LegacyProfiler* profiler = vm.enabledProfiler())
1101         profiler->didExecute(closure.oldCallFrame, closure.function);
1102
1103     return checkedReturn(result);
1104 }
1105
1106 JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
1107 {
1108     VM& vm = *scope->vm();
1109     SamplingScope samplingScope(this);
1110     
1111     ASSERT(scope->vm() == &callFrame->vm());
1112     ASSERT(!vm.exception());
1113     ASSERT(!vm.isCollectorBusy());
1114     if (vm.isCollectorBusy())
1115         return jsNull();
1116
1117     VMEntryScope entryScope(vm, scope->globalObject());
1118     if (!vm.isSafeToRecurse())
1119         return checkedReturn(throwStackOverflowError(callFrame));        
1120
1121     unsigned numVariables = eval->numVariables();
1122     int numFunctions = eval->numberOfFunctionDecls();
1123
1124     JSScope* variableObject;
1125     if ((numVariables || numFunctions) && eval->isStrictMode()) {
1126         scope = StrictEvalActivation::create(callFrame);
1127         variableObject = scope;
1128     } else {
1129         for (JSScope* node = scope; ; node = node->next()) {
1130             RELEASE_ASSERT(node);
1131             if (node->isVariableObject() && !node->isNameScopeObject()) {
1132                 variableObject = node;
1133                 break;
1134             }
1135         }
1136     }
1137
1138     JSObject* compileError = eval->prepareForExecution(callFrame, scope, CodeForCall);
1139     if (UNLIKELY(!!compileError))
1140         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1141     EvalCodeBlock* codeBlock = eval->codeBlock();
1142
1143     if (numVariables || numFunctions) {
1144         BatchedTransitionOptimizer optimizer(vm, variableObject);
1145         if (variableObject->next())
1146             variableObject->globalObject()->varInjectionWatchpoint()->fireAll();
1147
1148         for (unsigned i = 0; i < numVariables; ++i) {
1149             const Identifier& ident = codeBlock->variable(i);
1150             if (!variableObject->hasProperty(callFrame, ident)) {
1151                 PutPropertySlot slot(variableObject);
1152                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
1153             }
1154         }
1155
1156         for (int i = 0; i < numFunctions; ++i) {
1157             FunctionExecutable* function = codeBlock->functionDecl(i);
1158             PutPropertySlot slot(variableObject);
1159             variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
1160         }
1161     }
1162
1163     if (UNLIKELY(vm.watchdog.didFire(callFrame)))
1164         return throwTerminatedExecutionException(callFrame);
1165
1166     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1167
1168     ProtoCallFrame protoCallFrame;
1169     protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
1170
1171     if (LegacyProfiler* profiler = vm.enabledProfiler())
1172         profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
1173
1174     // Execute the code:
1175     JSValue result;
1176     {
1177         SamplingTool::CallRecord callRecord(m_sampler.get());
1178         Watchdog::Scope watchdogScope(vm.watchdog);
1179
1180         result = eval->generatedJITCode()->execute(&vm, &protoCallFrame);
1181     }
1182
1183     if (LegacyProfiler* profiler = vm.enabledProfiler())
1184         profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
1185
1186     return checkedReturn(result);
1187 }
1188
1189 NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID)
1190 {
1191     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
1192     if (!debugger)
1193         return;
1194     ASSERT(callFrame->codeBlock()->hasDebuggerRequests() || callFrame->hadException());
1195
1196     switch (debugHookID) {
1197         case DidEnterCallFrame:
1198             debugger->callEvent(callFrame);
1199             return;
1200         case WillLeaveCallFrame:
1201             debugger->returnEvent(callFrame);
1202             return;
1203         case WillExecuteStatement:
1204             debugger->atStatement(callFrame);
1205             return;
1206         case WillExecuteProgram:
1207             debugger->willExecuteProgram(callFrame);
1208             return;
1209         case DidExecuteProgram:
1210             debugger->didExecuteProgram(callFrame);
1211             return;
1212         case DidReachBreakpoint:
1213             debugger->didReachBreakpoint(callFrame);
1214             return;
1215     }
1216 }    
1217
1218 void Interpreter::enableSampler()
1219 {
1220 #if ENABLE(OPCODE_SAMPLING)
1221     if (!m_sampler) {
1222         m_sampler = adoptPtr(new SamplingTool(this));
1223         m_sampler->setup();
1224     }
1225 #endif
1226 }
1227 void Interpreter::dumpSampleData(ExecState* exec)
1228 {
1229 #if ENABLE(OPCODE_SAMPLING)
1230     if (m_sampler)
1231         m_sampler->dump(exec);
1232 #else
1233     UNUSED_PARAM(exec);
1234 #endif
1235 }
1236 void Interpreter::startSampling()
1237 {
1238 #if ENABLE(SAMPLING_THREAD)
1239     if (!m_sampleEntryDepth)
1240         SamplingThread::start();
1241
1242     m_sampleEntryDepth++;
1243 #endif
1244 }
1245 void Interpreter::stopSampling()
1246 {
1247 #if ENABLE(SAMPLING_THREAD)
1248     m_sampleEntryDepth--;
1249     if (!m_sampleEntryDepth)
1250         SamplingThread::stop();
1251 #endif
1252 }
1253
1254 } // namespace JSC