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