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