28ee1d0d1f00a4d013f1a52c29537f21a4e6dcaa
[WebKit-https.git] / Source / JavaScriptCore / interpreter / Interpreter.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "Interpreter.h"
32
33 #include "Arguments.h"
34 #include "BatchedTransitionOptimizer.h"
35 #include "CallFrameClosure.h"
36 #include "CallFrameInlines.h"
37 #include "CodeBlock.h"
38 #include "Heap.h"
39 #include "Debugger.h"
40 #include "DebuggerCallFrame.h"
41 #include "ErrorInstance.h"
42 #include "EvalCodeCache.h"
43 #include "ExceptionHelpers.h"
44 #include "GetterSetter.h"
45 #include "JSActivation.h"
46 #include "JSArray.h"
47 #include "JSBoundFunction.h"
48 #include "JSNameScope.h"
49 #include "JSNotAnObject.h"
50 #include "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->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     JSScope* scope = callFrame->scope();
443
444     if (Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger()) {
445         ClearExceptionScope scope(&callFrame->vm());
446         if (callFrame->callee())
447             debugger->returnEvent(callFrame);
448         else
449             debugger->didExecuteProgram(callFrame);
450         ASSERT(!callFrame->hadException());
451     }
452
453     JSValue activation;
454     if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) {
455 #if ENABLE(DFG_JIT)
456         RELEASE_ASSERT(!visitor->isInlinedFrame());
457 #endif
458         activation = callFrame->uncheckedActivation();
459         // Protect against the activation not being created, or the variable still being
460         // initialized to Undefined inside op_enter.
461         if (activation && activation.isCell()) {
462             JSActivation* activationObject = jsCast<JSActivation*>(activation);
463             // Protect against throwing exceptions after tear-off.
464             if (!activationObject->isTornOff())
465                 activationObject->tearOff(*scope->vm());
466         }
467     }
468
469     if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
470         if (Arguments* arguments = visitor->existingArguments()) {
471             if (activation && activation.isCell())
472                 arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
473 #if ENABLE(DFG_JIT)
474             else if (visitor->isInlinedFrame())
475                 arguments->tearOff(callFrame, visitor->inlineCallFrame());
476 #endif
477             else
478                 arguments->tearOff(callFrame);
479         }
480     }
481
482     return !visitor->callerIsVMEntryFrame();
483 }
484
485 static StackFrameCodeType getStackFrameCodeType(StackVisitor& visitor)
486 {
487     switch (visitor->codeType()) {
488     case StackVisitor::Frame::Eval:
489         return StackFrameEvalCode;
490     case StackVisitor::Frame::Function:
491         return StackFrameFunctionCode;
492     case StackVisitor::Frame::Global:
493         return StackFrameGlobalCode;
494     case StackVisitor::Frame::Native:
495         ASSERT_NOT_REACHED();
496         return StackFrameNativeCode;
497     }
498     RELEASE_ASSERT_NOT_REACHED();
499     return StackFrameGlobalCode;
500 }
501
502 void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column)
503 {
504     if (!codeBlock) {
505         line = 0;
506         column = 0;
507         return;
508     }
509
510     int divot = 0;
511     int unusedStartOffset = 0;
512     int unusedEndOffset = 0;
513     unsigned divotLine = 0;
514     unsigned divotColumn = 0;
515     expressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
516
517     line = divotLine + lineOffset;
518     column = divotColumn + (divotLine ? 1 : firstLineColumnOffset);
519 }
520
521 void StackFrame::expressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
522 {
523     codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
524     divot += characterOffset;
525 }
526
527 String StackFrame::toString(CallFrame* callFrame)
528 {
529     StringBuilder traceBuild;
530     String functionName = friendlyFunctionName(callFrame);
531     String sourceURL = friendlySourceURL();
532     traceBuild.append(functionName);
533     if (!sourceURL.isEmpty()) {
534         if (!functionName.isEmpty())
535             traceBuild.append('@');
536         traceBuild.append(sourceURL);
537         if (codeType != StackFrameNativeCode) {
538             unsigned line;
539             unsigned column;
540             computeLineAndColumn(line, column);
541
542             traceBuild.append(':');
543             traceBuild.appendNumber(line);
544             traceBuild.append(':');
545             traceBuild.appendNumber(column);
546         }
547     }
548     return traceBuild.toString().impl();
549 }
550
551 class GetStackTraceFunctor {
552 public:
553     GetStackTraceFunctor(VM& vm, Vector<StackFrame>& results, size_t remainingCapacity)
554         : m_vm(vm)
555         , m_results(results)
556         , m_remainingCapacityForFrameCapture(remainingCapacity)
557     {
558     }
559
560     StackVisitor::Status operator()(StackVisitor& visitor)
561     {
562         VM& vm = m_vm;
563         if (m_remainingCapacityForFrameCapture) {
564             if (visitor->isJSFrame() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) {
565                 CodeBlock* codeBlock = visitor->codeBlock();
566                 StackFrame s = {
567                     Strong<JSObject>(vm, visitor->callee()),
568                     getStackFrameCodeType(visitor),
569                     Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()),
570                     Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
571                     codeBlock->source(),
572                     codeBlock->ownerExecutable()->lineNo(),
573                     codeBlock->firstLineColumnOffset(),
574                     codeBlock->sourceOffset(),
575                     visitor->bytecodeOffset(),
576                     visitor->sourceURL()
577                 };
578                 m_results.append(s);
579             } else {
580                 StackFrame s = { Strong<JSObject>(vm, visitor->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
581                 m_results.append(s);
582             }
583     
584             m_remainingCapacityForFrameCapture--;
585             return StackVisitor::Continue;
586         }
587         return StackVisitor::Done;
588     }
589
590 private:
591     VM& m_vm;
592     Vector<StackFrame>& m_results;
593     size_t m_remainingCapacityForFrameCapture;
594 };
595
596 void Interpreter::getStackTrace(Vector<StackFrame>& results, size_t maxStackSize)
597 {
598     VM& vm = m_vm;
599     CallFrame* callFrame = vm.topCallFrame;
600     if (!callFrame)
601         return;
602
603     GetStackTraceFunctor functor(vm, results, maxStackSize);
604     callFrame->iterate(functor);
605 }
606
607 JSString* Interpreter::stackTraceAsString(ExecState* exec, Vector<StackFrame> stackTrace)
608 {
609     // FIXME: JSStringJoiner could be more efficient than StringBuilder here.
610     StringBuilder builder;
611     for (unsigned i = 0; i < stackTrace.size(); i++) {
612         builder.append(String(stackTrace[i].toString(exec)));
613         if (i != stackTrace.size() - 1)
614             builder.append('\n');
615     }
616     return jsString(&exec->vm(), builder.toString());
617 }
618
619 class GetExceptionHandlerFunctor {
620 public:
621     GetExceptionHandlerFunctor()
622         : m_handler(0)
623     {
624     }
625
626     HandlerInfo* handler() { return m_handler; }
627
628     StackVisitor::Status operator()(StackVisitor& visitor)
629     {
630         CodeBlock* codeBlock = visitor->codeBlock();
631         if (!codeBlock)
632             return StackVisitor::Continue;
633
634         unsigned bytecodeOffset = visitor->bytecodeOffset();
635         m_handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
636         if (m_handler)
637             return StackVisitor::Done;
638
639         return StackVisitor::Continue;
640     }
641
642 private:
643     HandlerInfo* m_handler;
644 };
645
646 class UnwindFunctor {
647 public:
648     UnwindFunctor(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
649         : m_vmEntryFrame(vmEntryFrame)
650         , m_callFrame(callFrame)
651         , m_isTermination(isTermination)
652         , m_codeBlock(codeBlock)
653         , m_handler(handler)
654     {
655     }
656
657     StackVisitor::Status operator()(StackVisitor& visitor)
658     {
659         VM& vm = m_callFrame->vm();
660         m_vmEntryFrame = visitor->vmEntryFrame();
661         m_callFrame = visitor->callFrame();
662         m_codeBlock = visitor->codeBlock();
663         unsigned bytecodeOffset = visitor->bytecodeOffset();
664
665         if (m_isTermination || !(m_handler = m_codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
666             if (!unwindCallFrame(visitor)) {
667                 if (LegacyProfiler* profiler = vm.enabledProfiler())
668                     profiler->exceptionUnwind(m_callFrame);
669                 return StackVisitor::Done;
670             }
671         } else
672             return StackVisitor::Done;
673
674         return StackVisitor::Continue;
675     }
676
677 private:
678     VMEntryFrame*& m_vmEntryFrame;
679     CallFrame*& m_callFrame;
680     bool m_isTermination;
681     CodeBlock*& m_codeBlock;
682     HandlerInfo*& m_handler;
683 };
684
685 NEVER_INLINE HandlerInfo* Interpreter::unwind(VMEntryFrame*& vmEntryFrame, CallFrame*& callFrame, JSValue& exceptionValue)
686 {
687     CodeBlock* codeBlock = callFrame->codeBlock();
688     ASSERT(codeBlock);
689     bool isTermination = false;
690
691     ASSERT(!exceptionValue.isEmpty());
692     ASSERT(!exceptionValue.isCell() || exceptionValue.asCell());
693     // This shouldn't be possible (hence the assertions), but we're already in the slowest of
694     // slow cases, so let's harden against it anyway to be safe.
695     if (exceptionValue.isEmpty() || (exceptionValue.isCell() && !exceptionValue.asCell()))
696         exceptionValue = jsNull();
697
698     if (exceptionValue.isObject())
699         isTermination = isTerminatedExecutionException(asObject(exceptionValue));
700
701     ASSERT(callFrame->vm().exceptionStack().size());
702
703     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
704     if (debugger && debugger->needsExceptionCallbacks()) {
705         // We need to clear the exception and the exception stack here in order to see if a new exception happens.
706         // Afterwards, the values are put back to continue processing this error.
707         ClearExceptionScope scope(&callFrame->vm());
708         // This code assumes that if the debugger is enabled then there is no inlining.
709         // If that assumption turns out to be false then we'll ignore the inlined call
710         // frames.
711         // https://bugs.webkit.org/show_bug.cgi?id=121754
712
713         bool hasHandler;
714         if (isTermination)
715             hasHandler = false;
716         else {
717             GetExceptionHandlerFunctor functor;
718             callFrame->iterate(functor);
719             hasHandler = !!functor.handler();
720         }
721
722         debugger->exception(callFrame, exceptionValue, hasHandler);
723         ASSERT(!callFrame->hadException());
724     }
725
726     // Calculate an exception handler vPC, unwinding call frames as necessary.
727     HandlerInfo* handler = 0;
728     VM& vm = callFrame->vm();
729     ASSERT(callFrame == vm.topCallFrame);
730     UnwindFunctor functor(vmEntryFrame, callFrame, isTermination, codeBlock, handler);
731     callFrame->iterate(functor);
732     if (!handler)
733         return 0;
734
735     if (LegacyProfiler* profiler = vm.enabledProfiler())
736         profiler->exceptionUnwind(callFrame);
737
738     // Unwind the scope chain within the exception handler's call frame.
739     int targetScopeDepth = handler->scopeDepth;
740     if (codeBlock->needsActivation() && callFrame->hasActivation())
741         ++targetScopeDepth;
742
743     JSScope* scope = callFrame->scope();
744     int scopeDelta = scope->depth() - targetScopeDepth;
745     RELEASE_ASSERT(scopeDelta >= 0);
746
747     while (scopeDelta--)
748         scope = scope->next();
749     callFrame->setScope(scope);
750
751     return handler;
752 }
753
754 static inline JSValue checkedReturn(JSValue returnValue)
755 {
756     ASSERT(returnValue);
757     return returnValue;
758 }
759
760 static inline JSObject* checkedReturn(JSObject* returnValue)
761 {
762     ASSERT(returnValue);
763     return returnValue;
764 }
765
766 class SamplingScope {
767 public:
768     SamplingScope(Interpreter* interpreter)
769         : m_interpreter(interpreter)
770     {
771         interpreter->startSampling();
772     }
773     ~SamplingScope()
774     {
775         m_interpreter->stopSampling();
776     }
777 private:
778     Interpreter* m_interpreter;
779 };
780
781 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
782 {
783     SamplingScope samplingScope(this);
784     
785     JSScope* scope = callFrame->scope();
786     VM& vm = *scope->vm();
787
788     ASSERT(!vm.exception());
789     ASSERT(!vm.isCollectorBusy());
790     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
791     if (vm.isCollectorBusy())
792         return jsNull();
793
794     if (!vm.isSafeToRecurse())
795         return checkedReturn(throwStackOverflowError(callFrame));
796
797     // First check if the "program" is actually just a JSON object. If so,
798     // we'll handle the JSON object here. Else, we'll handle real JS code
799     // below at failedJSONP.
800
801     Vector<JSONPData> JSONPData;
802     bool parseResult;
803     const String programSource = program->source().toString();
804     if (programSource.isNull())
805         return jsUndefined();
806     if (programSource.is8Bit()) {
807         LiteralParser<LChar> literalParser(callFrame, programSource.characters8(), programSource.length(), JSONP);
808         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
809     } else {
810         LiteralParser<UChar> literalParser(callFrame, programSource.characters16(), programSource.length(), JSONP);
811         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
812     }
813
814     if (parseResult) {
815         JSGlobalObject* globalObject = scope->globalObject();
816         JSValue result;
817         for (unsigned entry = 0; entry < JSONPData.size(); entry++) {
818             Vector<JSONPPathEntry> JSONPPath;
819             JSONPPath.swap(JSONPData[entry].m_path);
820             JSValue JSONPValue = JSONPData[entry].m_value.get();
821             if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
822                 globalObject->addVar(callFrame, JSONPPath[0].m_pathEntryName);
823                 PutPropertySlot slot(globalObject);
824                 globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
825                 result = jsUndefined();
826                 continue;
827             }
828             JSValue baseObject(globalObject);
829             for (unsigned i = 0; i < JSONPPath.size() - 1; i++) {
830                 ASSERT(JSONPPath[i].m_type != JSONPPathEntryTypeDeclare);
831                 switch (JSONPPath[i].m_type) {
832                 case JSONPPathEntryTypeDot: {
833                     if (i == 0) {
834                         PropertySlot slot(globalObject);
835                         if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
836                             if (entry)
837                                 return callFrame->vm().throwException(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
838                             goto failedJSONP;
839                         }
840                         baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
841                     } else
842                         baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathEntryName);
843                     if (callFrame->hadException())
844                         return jsUndefined();
845                     continue;
846                 }
847                 case JSONPPathEntryTypeLookup: {
848                     baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathIndex);
849                     if (callFrame->hadException())
850                         return jsUndefined();
851                     continue;
852                 }
853                 default:
854                     RELEASE_ASSERT_NOT_REACHED();
855                     return jsUndefined();
856                 }
857             }
858             PutPropertySlot slot(baseObject);
859             switch (JSONPPath.last().m_type) {
860             case JSONPPathEntryTypeCall: {
861                 JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
862                 if (callFrame->hadException())
863                     return jsUndefined();
864                 CallData callData;
865                 CallType callType = getCallData(function, callData);
866                 if (callType == CallTypeNone)
867                     return callFrame->vm().throwException(callFrame, createNotAFunctionError(callFrame, function));
868                 MarkedArgumentBuffer jsonArg;
869                 jsonArg.append(JSONPValue);
870                 JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
871                 JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
872                 if (callFrame->hadException())
873                     return jsUndefined();
874                 break;
875             }
876             case JSONPPathEntryTypeDot: {
877                 baseObject.put(callFrame, JSONPPath.last().m_pathEntryName, JSONPValue, slot);
878                 if (callFrame->hadException())
879                     return jsUndefined();
880                 break;
881             }
882             case JSONPPathEntryTypeLookup: {
883                 baseObject.putByIndex(callFrame, JSONPPath.last().m_pathIndex, JSONPValue, slot.isStrictMode());
884                 if (callFrame->hadException())
885                     return jsUndefined();
886                 break;
887             }
888             default:
889                 RELEASE_ASSERT_NOT_REACHED();
890                     return jsUndefined();
891             }
892             result = JSONPValue;
893         }
894         return result;
895     }
896 failedJSONP:
897     // If we get here, then we have already proven that the script is not a JSON
898     // object.
899
900     VMEntryScope entryScope(vm, scope->globalObject());
901
902     // Compile source to bytecode if necessary:
903     if (JSObject* error = program->initializeGlobalProperties(vm, callFrame, scope))
904         return checkedReturn(callFrame->vm().throwException(callFrame, error));
905
906     if (JSObject* error = program->prepareForExecution(callFrame, nullptr, &scope, CodeForCall))
907         return checkedReturn(callFrame->vm().throwException(callFrame, error));
908
909     ProgramCodeBlock* codeBlock = program->codeBlock();
910
911     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
912         return throwTerminatedExecutionException(callFrame);
913
914     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
915
916     ProtoCallFrame protoCallFrame;
917     protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
918
919     if (LegacyProfiler* profiler = vm.enabledProfiler())
920         profiler->willExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
921
922     // Execute the code:
923     JSValue result;
924     {
925         SamplingTool::CallRecord callRecord(m_sampler.get());
926         Watchdog::Scope watchdogScope(vm.watchdog.get());
927
928         result = program->generatedJITCode()->execute(&vm, &protoCallFrame);
929     }
930
931     if (LegacyProfiler* profiler = vm.enabledProfiler())
932         profiler->didExecute(callFrame, program->sourceURL(), program->lineNo(), program->startColumn());
933
934     return checkedReturn(result);
935 }
936
937 JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
938 {
939     VM& vm = callFrame->vm();
940     ASSERT(!callFrame->hadException());
941     ASSERT(!vm.isCollectorBusy());
942     if (vm.isCollectorBusy())
943         return jsNull();
944
945     bool isJSCall = (callType == CallTypeJS);
946     JSScope* scope;
947     CodeBlock* newCodeBlock;
948     size_t argsCount = 1 + args.size(); // implicit "this" parameter
949
950     if (isJSCall)
951         scope = callData.js.scope;
952     else {
953         ASSERT(callType == CallTypeHost);
954         scope = callFrame->scope();
955     }
956
957     VMEntryScope entryScope(vm, scope->globalObject());
958     if (!vm.isSafeToRecurse())
959         return checkedReturn(throwStackOverflowError(callFrame));
960
961     if (isJSCall) {
962         // Compile the callee:
963         JSObject* compileError = callData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(function), &scope, CodeForCall);
964         if (UNLIKELY(!!compileError)) {
965             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
966         }
967         newCodeBlock = callData.js.functionExecutable->codeBlockForCall();
968         ASSERT(!!newCodeBlock);
969         newCodeBlock->m_shouldAlwaysBeInlined = false;
970     } else
971         newCodeBlock = 0;
972
973     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
974         return throwTerminatedExecutionException(callFrame);
975
976     ProtoCallFrame protoCallFrame;
977     protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
978
979     if (LegacyProfiler* profiler = vm.enabledProfiler())
980         profiler->willExecute(callFrame, function);
981
982     JSValue result;
983     {
984         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
985         Watchdog::Scope watchdogScope(vm.watchdog.get());
986
987         // Execute the code:
988         if (isJSCall)
989             result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame);
990         else {
991             result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));
992             if (callFrame->hadException())
993                 result = jsNull();
994         }
995     }
996
997     if (LegacyProfiler* profiler = vm.enabledProfiler())
998         profiler->didExecute(callFrame, function);
999
1000     return checkedReturn(result);
1001 }
1002
1003 JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
1004 {
1005     VM& vm = callFrame->vm();
1006     ASSERT(!callFrame->hadException());
1007     ASSERT(!vm.isCollectorBusy());
1008     // We throw in this case because we have to return something "valid" but we're
1009     // already in an invalid state.
1010     if (vm.isCollectorBusy())
1011         return checkedReturn(throwStackOverflowError(callFrame));
1012
1013     bool isJSConstruct = (constructType == ConstructTypeJS);
1014     JSScope* scope;
1015     CodeBlock* newCodeBlock;
1016     size_t argsCount = 1 + args.size(); // implicit "this" parameter
1017
1018     if (isJSConstruct)
1019         scope = constructData.js.scope;
1020     else {
1021         ASSERT(constructType == ConstructTypeHost);
1022         scope = callFrame->scope();
1023     }
1024
1025     VMEntryScope entryScope(vm, scope->globalObject());
1026     if (!vm.isSafeToRecurse())
1027         return checkedReturn(throwStackOverflowError(callFrame));
1028
1029     if (isJSConstruct) {
1030         // Compile the callee:
1031         JSObject* compileError = constructData.js.functionExecutable->prepareForExecution(callFrame, jsCast<JSFunction*>(constructor), &scope, CodeForConstruct);
1032         if (UNLIKELY(!!compileError)) {
1033             return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1034         }
1035         newCodeBlock = constructData.js.functionExecutable->codeBlockForConstruct();
1036         ASSERT(!!newCodeBlock);
1037         newCodeBlock->m_shouldAlwaysBeInlined = false;
1038     } else
1039         newCodeBlock = 0;
1040
1041     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
1042         return throwTerminatedExecutionException(callFrame);
1043
1044     ProtoCallFrame protoCallFrame;
1045     protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
1046
1047     if (LegacyProfiler* profiler = vm.enabledProfiler())
1048         profiler->willExecute(callFrame, constructor);
1049
1050     JSValue result;
1051     {
1052         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
1053         Watchdog::Scope watchdogScope(vm.watchdog.get());
1054
1055         // Execute the code.
1056         if (isJSConstruct)
1057             result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame);
1058         else {
1059             result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));
1060
1061             if (!callFrame->hadException())
1062                 RELEASE_ASSERT(result.isObject());
1063         }
1064     }
1065
1066     if (LegacyProfiler* profiler = vm.enabledProfiler())
1067         profiler->didExecute(callFrame, constructor);
1068
1069     if (callFrame->hadException())
1070         return 0;
1071     ASSERT(result.isObject());
1072     return checkedReturn(asObject(result));
1073 }
1074
1075 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
1076 {
1077     VM& vm = *scope->vm();
1078     ASSERT(!vm.exception());
1079     
1080     if (vm.isCollectorBusy())
1081         return CallFrameClosure();
1082
1083     // Compile the callee:
1084     JSObject* error = functionExecutable->prepareForExecution(callFrame, function, &scope, CodeForCall);
1085     if (error) {
1086         callFrame->vm().throwException(callFrame, error);
1087         return CallFrameClosure();
1088     }
1089     CodeBlock* newCodeBlock = functionExecutable->codeBlockForCall();
1090     newCodeBlock->m_shouldAlwaysBeInlined = false;
1091
1092     size_t argsCount = argumentCountIncludingThis;
1093
1094     protoCallFrame->init(newCodeBlock, scope, function, jsUndefined(), argsCount, args);
1095     // Return the successful closure:
1096     CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
1097     return result;
1098 }
1099
1100 JSValue Interpreter::execute(CallFrameClosure& closure) 
1101 {
1102     VM& vm = *closure.vm;
1103     SamplingScope samplingScope(this);
1104     
1105     ASSERT(!vm.isCollectorBusy());
1106     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
1107     if (vm.isCollectorBusy())
1108         return jsNull();
1109
1110     StackStats::CheckPoint stackCheckPoint;
1111     closure.resetCallFrame();
1112
1113     if (LegacyProfiler* profiler = vm.enabledProfiler())
1114         profiler->willExecute(closure.oldCallFrame, closure.function);
1115
1116     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(closure.oldCallFrame)))
1117         return throwTerminatedExecutionException(closure.oldCallFrame);
1118
1119     // Execute the code:
1120     JSValue result;
1121     {
1122         SamplingTool::CallRecord callRecord(m_sampler.get());
1123         Watchdog::Scope watchdogScope(vm.watchdog.get());
1124
1125         result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.protoCallFrame);
1126     }
1127
1128     if (LegacyProfiler* profiler = vm.enabledProfiler())
1129         profiler->didExecute(closure.oldCallFrame, closure.function);
1130
1131     return checkedReturn(result);
1132 }
1133
1134 JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
1135 {
1136     VM& vm = *scope->vm();
1137     SamplingScope samplingScope(this);
1138     
1139     ASSERT(scope->vm() == &callFrame->vm());
1140     ASSERT(!vm.exception());
1141     ASSERT(!vm.isCollectorBusy());
1142     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
1143     if (vm.isCollectorBusy())
1144         return jsNull();
1145
1146     VMEntryScope entryScope(vm, scope->globalObject());
1147     if (!vm.isSafeToRecurse())
1148         return checkedReturn(throwStackOverflowError(callFrame));        
1149
1150     unsigned numVariables = eval->numVariables();
1151     int numFunctions = eval->numberOfFunctionDecls();
1152
1153     JSScope* variableObject;
1154     if ((numVariables || numFunctions) && eval->isStrictMode()) {
1155         scope = StrictEvalActivation::create(callFrame);
1156         variableObject = scope;
1157     } else {
1158         for (JSScope* node = scope; ; node = node->next()) {
1159             RELEASE_ASSERT(node);
1160             if (node->isVariableObject() && !node->isNameScopeObject()) {
1161                 variableObject = node;
1162                 break;
1163             }
1164         }
1165     }
1166
1167     JSObject* compileError = eval->prepareForExecution(callFrame, nullptr, &scope, CodeForCall);
1168     if (UNLIKELY(!!compileError))
1169         return checkedReturn(callFrame->vm().throwException(callFrame, compileError));
1170     EvalCodeBlock* codeBlock = eval->codeBlock();
1171
1172     if (numVariables || numFunctions) {
1173         BatchedTransitionOptimizer optimizer(vm, variableObject);
1174         if (variableObject->next())
1175             variableObject->globalObject()->varInjectionWatchpoint()->fireAll("Executed eval, fired VarInjection watchpoint");
1176
1177         for (unsigned i = 0; i < numVariables; ++i) {
1178             const Identifier& ident = codeBlock->variable(i);
1179             if (!variableObject->hasProperty(callFrame, ident)) {
1180                 PutPropertySlot slot(variableObject);
1181                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
1182             }
1183         }
1184
1185         for (int i = 0; i < numFunctions; ++i) {
1186             FunctionExecutable* function = codeBlock->functionDecl(i);
1187             PutPropertySlot slot(variableObject);
1188             variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
1189         }
1190     }
1191
1192     if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame)))
1193         return throwTerminatedExecutionException(callFrame);
1194
1195     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1196
1197     ProtoCallFrame protoCallFrame;
1198     protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
1199
1200     if (LegacyProfiler* profiler = vm.enabledProfiler())
1201         profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
1202
1203     // Execute the code:
1204     JSValue result;
1205     {
1206         SamplingTool::CallRecord callRecord(m_sampler.get());
1207         Watchdog::Scope watchdogScope(vm.watchdog.get());
1208
1209         result = eval->generatedJITCode()->execute(&vm, &protoCallFrame);
1210     }
1211
1212     if (LegacyProfiler* profiler = vm.enabledProfiler())
1213         profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo(), eval->startColumn());
1214
1215     return checkedReturn(result);
1216 }
1217
1218 NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID)
1219 {
1220     Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger();
1221     if (!debugger)
1222         return;
1223
1224     ASSERT(callFrame->codeBlock()->hasDebuggerRequests());
1225     ASSERT(!callFrame->hadException());
1226
1227     switch (debugHookID) {
1228         case DidEnterCallFrame:
1229             debugger->callEvent(callFrame);
1230             break;
1231         case WillLeaveCallFrame:
1232             debugger->returnEvent(callFrame);
1233             break;
1234         case WillExecuteStatement:
1235             debugger->atStatement(callFrame);
1236             break;
1237         case WillExecuteProgram:
1238             debugger->willExecuteProgram(callFrame);
1239             break;
1240         case DidExecuteProgram:
1241             debugger->didExecuteProgram(callFrame);
1242             break;
1243         case DidReachBreakpoint:
1244             debugger->didReachBreakpoint(callFrame);
1245             break;
1246     }
1247     ASSERT(!callFrame->hadException());
1248 }    
1249
1250 void Interpreter::enableSampler()
1251 {
1252 #if ENABLE(OPCODE_SAMPLING)
1253     if (!m_sampler) {
1254         m_sampler = adoptPtr(new SamplingTool(this));
1255         m_sampler->setup();
1256     }
1257 #endif
1258 }
1259 void Interpreter::dumpSampleData(ExecState* exec)
1260 {
1261 #if ENABLE(OPCODE_SAMPLING)
1262     if (m_sampler)
1263         m_sampler->dump(exec);
1264 #else
1265     UNUSED_PARAM(exec);
1266 #endif
1267 }
1268 void Interpreter::startSampling()
1269 {
1270 #if ENABLE(SAMPLING_THREAD)
1271     if (!m_sampleEntryDepth)
1272         SamplingThread::start();
1273
1274     m_sampleEntryDepth++;
1275 #endif
1276 }
1277 void Interpreter::stopSampling()
1278 {
1279 #if ENABLE(SAMPLING_THREAD)
1280     m_sampleEntryDepth--;
1281     if (!m_sampleEntryDepth)
1282         SamplingThread::stop();
1283 #endif
1284 }
1285
1286 } // namespace JSC