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