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