2  * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved. 
   3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 
   5  * Redistribution and use in source and binary forms, with or without 
   6  * modification, are permitted provided that the following conditions 
   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. 
  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. 
  31 #include "Interpreter.h" 
  33 #include "Arguments.h" 
  34 #include "BatchedTransitionOptimizer.h" 
  35 #include "CallFrameClosure.h" 
  36 #include "CallFrameInlines.h" 
  37 #include "CodeBlock.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" 
  47 #include "JSBoundFunction.h" 
  48 #include "JSNameScope.h" 
  49 #include "JSNotAnObject.h" 
  50 #include "JSPropertyNameIterator.h" 
  51 #include "JSStackInlines.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" 
  62 #include "ProtoCallFrame.h" 
  63 #include "RegExpObject.h" 
  64 #include "RegExpPrototype.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" 
  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> 
  87 #define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (!defined(__llvm__)) 
  93 JSValue 
eval(CallFrame
* callFrame
) 
  95     if (!callFrame
->argumentCount()) 
  98     JSValue program 
= callFrame
->argument(0); 
  99     if (!program
.isString()) 
 102     TopCallFrameSetter 
topCallFrame(callFrame
->vm(), callFrame
); 
 103     String programSource 
= asString(program
)->value(callFrame
); 
 104     if (callFrame
->hadException()) 
 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
); 
 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()) 
 121                 LiteralParser
<UChar
> preparser(callFrame
, programSource
.characters16(), programSource
.length(), NonStrictJSON
); 
 122                 if (JSValue parsedObject 
= preparser
.tryLiteralParse()) 
 127         // If the literal parser bailed, it should not have thrown exceptions. 
 128         ASSERT(!callFrame
->vm().exception()); 
 130         eval 
= callerCodeBlock
->evalCodeCache().getSlow(callFrame
, callerCodeBlock
->ownerExecutable(), callerCodeBlock
->isStrictMode(), programSource
, callerScopeChain
); 
 132             return jsUndefined(); 
 135     JSValue thisValue 
= callerFrame
->thisValue(); 
 136     Interpreter
* interpreter 
= callFrame
->vm().interpreter
; 
 137     return interpreter
->execute(eval
, callFrame
, thisValue
, callerScopeChain
); 
 140 CallFrame
* sizeFrameForVarargs(CallFrame
* callFrame
, JSStack
* stack
, JSValue arguments
, int firstFreeRegister
, uint32_t firstVarArgOffset
) 
 142     if (!arguments
) { // f.apply(x, arguments), with arguments unmodified. 
 143         unsigned argumentCountIncludingThis 
= callFrame
->argumentCountIncludingThis(); 
 144         if (argumentCountIncludingThis 
> firstVarArgOffset
) 
 145             argumentCountIncludingThis 
-= firstVarArgOffset
; 
 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
); 
 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
); 
 168     if (!arguments
.isObject()) { 
 169         callFrame
->vm().throwException(callFrame
, createInvalidParameterError(callFrame
, "Function.prototype.apply", arguments
)); 
 173     if (asObject(arguments
)->classInfo() == Arguments::info()) { 
 174         Arguments
* argsObject 
= asArguments(arguments
); 
 175         unsigned argCount 
= argsObject
->length(callFrame
); 
 176         callFrame
->vm().varargsLength 
= argCount
; 
 177         if (argCount 
>= firstVarArgOffset
) 
 178             argCount 
-= firstVarArgOffset
; 
 181         unsigned paddedCalleeFrameOffset 
= WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister 
+ CallFrame::offsetFor(argCount 
+ 1)); 
 182         CallFrame
* newCallFrame 
= CallFrame::create(callFrame
->registers() - paddedCalleeFrameOffset
); 
 183         if (argCount 
> Arguments::MaxArguments 
|| !stack
->ensureCapacityFor(newCallFrame
->registers())) { 
 184             throwStackOverflowError(callFrame
); 
 190     if (isJSArray(arguments
)) { 
 191         JSArray
* array 
= asArray(arguments
); 
 192         unsigned argCount 
= array
->length(); 
 193         if (argCount 
>= firstVarArgOffset
) 
 194             argCount 
-= firstVarArgOffset
; 
 197         unsigned paddedCalleeFrameOffset 
= WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister 
+ CallFrame::offsetFor(argCount 
+ 1)); 
 198         CallFrame
* newCallFrame 
= CallFrame::create(callFrame
->registers() - paddedCalleeFrameOffset
); 
 199         if (argCount 
> Arguments::MaxArguments 
|| !stack
->ensureCapacityFor(newCallFrame
->registers())) { 
 200             throwStackOverflowError(callFrame
); 
 206     JSObject
* argObject 
= asObject(arguments
); 
 207     unsigned argCount 
= argObject
->get(callFrame
, callFrame
->propertyNames().length
).toUInt32(callFrame
); 
 208     callFrame
->vm().varargsLength 
= argCount
; 
 209     if (argCount 
>= firstVarArgOffset
) 
 210         argCount 
-= firstVarArgOffset
; 
 213     unsigned paddedCalleeFrameOffset 
= WTF::roundUpToMultipleOf(stackAlignmentRegisters(), -firstFreeRegister 
+ CallFrame::offsetFor(argCount 
+ 1)); 
 214     CallFrame
* newCallFrame 
= CallFrame::create(callFrame
->registers() - paddedCalleeFrameOffset
); 
 215     if (argCount 
> Arguments::MaxArguments 
|| !stack
->ensureCapacityFor(newCallFrame
->registers())) { 
 216         throwStackOverflowError(callFrame
); 
 222 void loadVarargs(CallFrame
* callFrame
, CallFrame
* newCallFrame
, JSValue thisValue
, JSValue arguments
, uint32_t firstVarArgOffset
) 
 224     if (!arguments
) { // f.apply(x, arguments), with arguments unmodified. 
 225         unsigned argumentCountIncludingThis 
= callFrame
->argumentCountIncludingThis(); 
 226         if (argumentCountIncludingThis 
> firstVarArgOffset
) 
 227             argumentCountIncludingThis 
-= firstVarArgOffset
; 
 229             argumentCountIncludingThis 
= 1; 
 230         newCallFrame
->setArgumentCountIncludingThis(argumentCountIncludingThis
); 
 231         newCallFrame
->setThisValue(thisValue
); 
 232         for (size_t i 
= firstVarArgOffset
; i 
< callFrame
->argumentCount(); ++i
) 
 233             newCallFrame
->setArgument(i 
- firstVarArgOffset
, callFrame
->argumentAfterCapture(i
)); 
 237     if (arguments
.isUndefinedOrNull()) { 
 238         newCallFrame
->setArgumentCountIncludingThis(1); 
 239         newCallFrame
->setThisValue(thisValue
); 
 243     if (asObject(arguments
)->classInfo() == Arguments::info()) { 
 244         Arguments
* argsObject 
= asArguments(arguments
); 
 245         unsigned argCount 
= callFrame
->vm().varargsLength
; 
 246         callFrame
->vm().varargsLength 
= 0; 
 247         if (argCount 
>= firstVarArgOffset
) { 
 248             argCount 
-= firstVarArgOffset
; 
 249             newCallFrame
->setArgumentCountIncludingThis(argCount 
+ 1); 
 250             argsObject
->copyToArguments(callFrame
, newCallFrame
, argCount
, firstVarArgOffset
); 
 252             newCallFrame
->setArgumentCountIncludingThis(1); 
 253         newCallFrame
->setThisValue(thisValue
); 
 257     if (isJSArray(arguments
)) { 
 258         JSArray
* array 
= asArray(arguments
); 
 259         unsigned argCount 
= array
->length(); 
 260         if (argCount 
>= firstVarArgOffset
) { 
 261             argCount 
-= firstVarArgOffset
; 
 262             newCallFrame
->setArgumentCountIncludingThis(argCount 
+ 1); 
 263             array
->copyToArguments(callFrame
, newCallFrame
, argCount
, firstVarArgOffset
); 
 265             newCallFrame
->setArgumentCountIncludingThis(1); 
 266         newCallFrame
->setThisValue(thisValue
); 
 270     unsigned argCount 
= callFrame
->vm().varargsLength
; 
 271     if (argCount 
>= firstVarArgOffset
) { 
 272         argCount 
-= firstVarArgOffset
; 
 273         newCallFrame
->setArgumentCountIncludingThis(argCount 
+ 1); 
 275         newCallFrame
->setArgumentCountIncludingThis(1); 
 277     newCallFrame
->setThisValue(thisValue
); 
 278     for (size_t i 
= 0; i 
< argCount
; ++i
) { 
 279         newCallFrame
->setArgument(i
, asObject(arguments
)->get(callFrame
, i 
+ firstVarArgOffset
)); 
 280         if (UNLIKELY(callFrame
->vm().exception())) 
 285 Interpreter::Interpreter(VM
& vm
) 
 286     : m_sampleEntryDepth(0) 
 289     , m_errorHandlingModeReentry(0) 
 291     , m_initialized(false) 
 296 Interpreter::~Interpreter() 
 300 void Interpreter::initialize(bool canUseJIT
) 
 302     UNUSED_PARAM(canUseJIT
); 
 304 #if ENABLE(COMPUTED_GOTO_OPCODES) 
 305     m_opcodeTable 
= LLInt::opcodeMap(); 
 306     for (int i 
= 0; i 
< numOpcodeIDs
; ++i
) 
 307         m_opcodeIDTable
.add(m_opcodeTable
[i
], static_cast<OpcodeID
>(i
)); 
 311     m_initialized 
= true; 
 314 #if ENABLE(OPCODE_SAMPLING) 
 321 void Interpreter::dumpCallFrame(CallFrame
*) 
 327 void Interpreter::dumpCallFrame(CallFrame
* callFrame
) 
 329     callFrame
->codeBlock()->dumpBytecode(); 
 330     dumpRegisters(callFrame
); 
 333 class DumpRegisterFunctor 
{ 
 335     DumpRegisterFunctor(const Register
*& it
) 
 336         : m_hasSkippedFirstFrame(false) 
 341     StackVisitor::Status 
operator()(StackVisitor
& visitor
) 
 343         if (!m_hasSkippedFirstFrame
) { 
 344             m_hasSkippedFirstFrame 
= true; 
 345             return StackVisitor::Continue
; 
 349         unsigned unusedColumn 
= 0; 
 350         visitor
->computeLineAndColumn(line
, unusedColumn
); 
 351         dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", m_it
, visitor
->bytecodeOffset(), line
); 
 353         return StackVisitor::Done
; 
 357     bool m_hasSkippedFirstFrame
; 
 358     const Register
*& m_it
; 
 361 void Interpreter::dumpRegisters(CallFrame
* callFrame
) 
 363     dataLogF("Register frame: \n\n"); 
 364     dataLogF("-----------------------------------------------------------------------------\n"); 
 365     dataLogF("            use            |   address  |                value               \n"); 
 366     dataLogF("-----------------------------------------------------------------------------\n"); 
 368     CodeBlock
* codeBlock 
= callFrame
->codeBlock(); 
 372     it 
= callFrame
->registers() + JSStack::ThisArgument 
+ callFrame
->argumentCount(); 
 373     end 
= callFrame
->registers() + JSStack::ThisArgument 
- 1; 
 375         JSValue v 
= it
->jsValue(); 
 376         int registerNumber 
= it 
- callFrame
->registers(); 
 377         String name 
= codeBlock
->nameForRegister(VirtualRegister(registerNumber
)); 
 378         dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber
, name
.ascii().data(), it
, toCString(v
).data(), (long long)JSValue::encode(v
)); 
 382     dataLogF("-----------------------------------------------------------------------------\n"); 
 383     dataLogF("[ArgumentCount]            | %10p | %lu \n", it
, (unsigned long) callFrame
->argumentCount()); 
 385     dataLogF("[CallerFrame]              | %10p | %p \n", it
, callFrame
->callerFrame()); 
 387     dataLogF("[Callee]                   | %10p | %p \n", it
, callFrame
->callee()); 
 389     dataLogF("[ScopeChain]               | %10p | %p \n", it
, callFrame
->scope()); 
 392     AbstractPC pc 
= callFrame
->abstractReturnPC(callFrame
->vm()); 
 393     if (pc
.hasJITReturnAddress()) 
 394         dataLogF("[ReturnJITPC]              | %10p | %p \n", it
, pc
.jitReturnAddress().value()); 
 397     DumpRegisterFunctor 
functor(it
); 
 398     callFrame
->iterate(functor
); 
 400     dataLogF("[CodeBlock]                | %10p | %p \n", it
, callFrame
->codeBlock()); 
 402     dataLogF("-----------------------------------------------------------------------------\n"); 
 404     end 
= it 
- codeBlock
->m_numVars
; 
 407             JSValue v 
= it
->jsValue(); 
 408             int registerNumber 
= it 
- callFrame
->registers(); 
 409             String name 
= codeBlock
->nameForRegister(VirtualRegister(registerNumber
)); 
 410             dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber
, name
.ascii().data(), it
, toCString(v
).data(), (long long)JSValue::encode(v
)); 
 414     dataLogF("-----------------------------------------------------------------------------\n"); 
 416     end 
= it 
- codeBlock
->m_numCalleeRegisters 
+ codeBlock
->m_numVars
; 
 419             JSValue v 
= (*it
).jsValue(); 
 420             int registerNumber 
= it 
- callFrame
->registers(); 
 421             dataLogF("[r% 3d]                     | %10p | %-16s 0x%lld \n", registerNumber
, it
, toCString(v
).data(), (long long)JSValue::encode(v
)); 
 425     dataLogF("-----------------------------------------------------------------------------\n"); 
 430 bool Interpreter::isOpcode(Opcode opcode
) 
 432 #if ENABLE(COMPUTED_GOTO_OPCODES) 
 433     return opcode 
!= HashTraits
<Opcode
>::emptyValue() 
 434         && !HashTraits
<Opcode
>::isDeletedValue(opcode
) 
 435         && m_opcodeIDTable
.contains(opcode
); 
 437     return opcode 
>= 0 && opcode 
<= op_end
; 
 441 static bool unwindCallFrame(StackVisitor
& visitor
) 
 443     CallFrame
* callFrame 
= visitor
->callFrame(); 
 444     CodeBlock
* codeBlock 
= visitor
->codeBlock(); 
 445     JSScope
* scope 
= callFrame
->scope(); 
 447     if (Debugger
* debugger 
= callFrame
->vmEntryGlobalObject()->debugger()) { 
 448         ClearExceptionScope 
scope(&callFrame
->vm()); 
 449         if (callFrame
->callee()) 
 450             debugger
->returnEvent(callFrame
); 
 452             debugger
->didExecuteProgram(callFrame
); 
 453         ASSERT(!callFrame
->hadException()); 
 457     if (codeBlock
->codeType() == FunctionCode 
&& codeBlock
->needsActivation()) { 
 459         RELEASE_ASSERT(!visitor
->isInlinedFrame()); 
 461         activation 
= callFrame
->uncheckedActivation(); 
 462         // Protect against the activation not being created, or the variable still being 
 463         // initialized to Undefined inside op_enter. 
 464         if (activation 
&& activation
.isCell()) { 
 465             JSActivation
* activationObject 
= jsCast
<JSActivation
*>(activation
); 
 466             // Protect against throwing exceptions after tear-off. 
 467             if (!activationObject
->isTornOff()) 
 468                 activationObject
->tearOff(*scope
->vm()); 
 472     if (codeBlock
->codeType() == FunctionCode 
&& codeBlock
->usesArguments()) { 
 473         if (Arguments
* arguments 
= visitor
->existingArguments()) { 
 474             if (activation 
&& activation
.isCell()) 
 475                 arguments
->didTearOffActivation(callFrame
, jsCast
<JSActivation
*>(activation
)); 
 477             else if (visitor
->isInlinedFrame()) 
 478                 arguments
->tearOff(callFrame
, visitor
->inlineCallFrame()); 
 481                 arguments
->tearOff(callFrame
); 
 485     CallFrame
* callerFrame 
= callFrame
->callerFrame(); 
 486     return !callerFrame
->isVMEntrySentinel(); 
 489 static StackFrameCodeType 
getStackFrameCodeType(StackVisitor
& visitor
) 
 491     switch (visitor
->codeType()) { 
 492     case StackVisitor::Frame::Eval
: 
 493         return StackFrameEvalCode
; 
 494     case StackVisitor::Frame::Function
: 
 495         return StackFrameFunctionCode
; 
 496     case StackVisitor::Frame::Global
: 
 497         return StackFrameGlobalCode
; 
 498     case StackVisitor::Frame::Native
: 
 499         ASSERT_NOT_REACHED(); 
 500         return StackFrameNativeCode
; 
 502     RELEASE_ASSERT_NOT_REACHED(); 
 503     return StackFrameGlobalCode
; 
 506 void StackFrame::computeLineAndColumn(unsigned& line
, unsigned& column
) 
 515     int unusedStartOffset 
= 0; 
 516     int unusedEndOffset 
= 0; 
 517     unsigned divotLine 
= 0; 
 518     unsigned divotColumn 
= 0; 
 519     expressionInfo(divot
, unusedStartOffset
, unusedEndOffset
, divotLine
, divotColumn
); 
 521     line 
= divotLine 
+ lineOffset
; 
 522     column 
= divotColumn 
+ (divotLine 
? 1 : firstLineColumnOffset
); 
 525 void StackFrame::expressionInfo(int& divot
, int& startOffset
, int& endOffset
, unsigned& line
, unsigned& column
) 
 527     codeBlock
->expressionRangeForBytecodeOffset(bytecodeOffset
, divot
, startOffset
, endOffset
, line
, column
); 
 528     divot 
+= characterOffset
; 
 531 String 
StackFrame::toString(CallFrame
* callFrame
) 
 533     StringBuilder traceBuild
; 
 534     String functionName 
= friendlyFunctionName(callFrame
); 
 535     String sourceURL 
= friendlySourceURL(); 
 536     traceBuild
.append(functionName
); 
 537     if (!sourceURL
.isEmpty()) { 
 538         if (!functionName
.isEmpty()) 
 539             traceBuild
.append('@'); 
 540         traceBuild
.append(sourceURL
); 
 541         if (codeType 
!= StackFrameNativeCode
) { 
 544             computeLineAndColumn(line
, column
); 
 546             traceBuild
.append(':'); 
 547             traceBuild
.appendNumber(line
); 
 548             traceBuild
.append(':'); 
 549             traceBuild
.appendNumber(column
); 
 552     return traceBuild
.toString().impl(); 
 555 class GetStackTraceFunctor 
{ 
 557     GetStackTraceFunctor(VM
& vm
, Vector
<StackFrame
>& results
, size_t remainingCapacity
) 
 560         , m_remainingCapacityForFrameCapture(remainingCapacity
) 
 564     StackVisitor::Status 
operator()(StackVisitor
& visitor
) 
 567         if (m_remainingCapacityForFrameCapture
) { 
 568             if (visitor
->isJSFrame() && !visitor
->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) { 
 569                 CodeBlock
* codeBlock 
= visitor
->codeBlock(); 
 571                     Strong
<JSObject
>(vm
, visitor
->callee()), 
 572                     getStackFrameCodeType(visitor
), 
 573                     Strong
<ExecutableBase
>(vm
, codeBlock
->ownerExecutable()), 
 574                     Strong
<UnlinkedCodeBlock
>(vm
, codeBlock
->unlinkedCodeBlock()), 
 576                     codeBlock
->ownerExecutable()->lineNo(), 
 577                     codeBlock
->firstLineColumnOffset(), 
 578                     codeBlock
->sourceOffset(), 
 579                     visitor
->bytecodeOffset(), 
 584                 StackFrame s 
= { Strong
<JSObject
>(vm
, visitor
->callee()), StackFrameNativeCode
, Strong
<ExecutableBase
>(), Strong
<UnlinkedCodeBlock
>(), 0, 0, 0, 0, 0, String()}; 
 588             m_remainingCapacityForFrameCapture
--; 
 589             return StackVisitor::Continue
; 
 591         return StackVisitor::Done
; 
 596     Vector
<StackFrame
>& m_results
; 
 597     size_t m_remainingCapacityForFrameCapture
; 
 600 void Interpreter::getStackTrace(Vector
<StackFrame
>& results
, size_t maxStackSize
) 
 603     ASSERT(!vm
.topCallFrame
->isVMEntrySentinel()); 
 604     CallFrame
* callFrame 
= vm
.topCallFrame
; 
 608     GetStackTraceFunctor 
functor(vm
, results
, maxStackSize
); 
 609     callFrame
->iterate(functor
); 
 612 JSString
* Interpreter::stackTraceAsString(ExecState
* exec
, Vector
<StackFrame
> stackTrace
) 
 614     // FIXME: JSStringJoiner could be more efficient than StringBuilder here. 
 615     StringBuilder builder
; 
 616     for (unsigned i 
= 0; i 
< stackTrace
.size(); i
++) { 
 617         builder
.append(String(stackTrace
[i
].toString(exec
))); 
 618         if (i 
!= stackTrace
.size() - 1) 
 619             builder
.append('\n'); 
 621     return jsString(&exec
->vm(), builder
.toString()); 
 624 class GetExceptionHandlerFunctor 
{ 
 626     GetExceptionHandlerFunctor() 
 631     HandlerInfo
* handler() { return m_handler
; } 
 633     StackVisitor::Status 
operator()(StackVisitor
& visitor
) 
 635         CodeBlock
* codeBlock 
= visitor
->codeBlock(); 
 637             return StackVisitor::Continue
; 
 639         unsigned bytecodeOffset 
= visitor
->bytecodeOffset(); 
 640         m_handler 
= codeBlock
->handlerForBytecodeOffset(bytecodeOffset
); 
 642             return StackVisitor::Done
; 
 644         return StackVisitor::Continue
; 
 648     HandlerInfo
* m_handler
; 
 651 class UnwindFunctor 
{ 
 653     UnwindFunctor(CallFrame
*& callFrame
, bool isTermination
, CodeBlock
*& codeBlock
, HandlerInfo
*& handler
) 
 654         : m_callFrame(callFrame
) 
 655         , m_isTermination(isTermination
) 
 656         , m_codeBlock(codeBlock
) 
 661     StackVisitor::Status 
operator()(StackVisitor
& visitor
) 
 663         VM
& vm 
= m_callFrame
->vm(); 
 664         m_callFrame 
= visitor
->callFrame(); 
 665         m_codeBlock 
= visitor
->codeBlock(); 
 666         unsigned bytecodeOffset 
= visitor
->bytecodeOffset(); 
 668         if (m_isTermination 
|| !(m_handler 
= m_codeBlock
->handlerForBytecodeOffset(bytecodeOffset
))) { 
 669             if (!unwindCallFrame(visitor
)) { 
 670                 if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
 671                     profiler
->exceptionUnwind(m_callFrame
); 
 672                 return StackVisitor::Done
; 
 675             return StackVisitor::Done
; 
 677         return StackVisitor::Continue
; 
 681     CallFrame
*& m_callFrame
; 
 682     bool m_isTermination
; 
 683     CodeBlock
*& m_codeBlock
; 
 684     HandlerInfo
*& m_handler
; 
 687 NEVER_INLINE HandlerInfo
* Interpreter::unwind(CallFrame
*& callFrame
, JSValue
& exceptionValue
) 
 689     if (callFrame
->isVMEntrySentinel()) { 
 690         // This happens when we throw stack overflow in a function that is called 
 691         // directly from callToJavaScript. Stack overflow throws the exception in the 
 692         // context of the caller. In that case the caller is the sentinel frame. The 
 693         // right thing to do is to pretend that the exception is uncaught so that we 
 694         // go to the uncaught exception handler, which returns through callToJavaScript. 
 698     CodeBlock
* codeBlock 
= callFrame
->codeBlock(); 
 700     bool isTermination 
= false; 
 702     ASSERT(!exceptionValue
.isEmpty()); 
 703     ASSERT(!exceptionValue
.isCell() || exceptionValue
.asCell()); 
 704     // This shouldn't be possible (hence the assertions), but we're already in the slowest of 
 705     // slow cases, so let's harden against it anyway to be safe. 
 706     if (exceptionValue
.isEmpty() || (exceptionValue
.isCell() && !exceptionValue
.asCell())) 
 707         exceptionValue 
= jsNull(); 
 709     if (exceptionValue
.isObject()) 
 710         isTermination 
= isTerminatedExecutionException(asObject(exceptionValue
)); 
 712     ASSERT(callFrame
->vm().exceptionStack().size()); 
 714     Debugger
* debugger 
= callFrame
->vmEntryGlobalObject()->debugger(); 
 715     if (debugger 
&& debugger
->needsExceptionCallbacks()) { 
 716         // We need to clear the exception and the exception stack here in order to see if a new exception happens. 
 717         // Afterwards, the values are put back to continue processing this error. 
 718         ClearExceptionScope 
scope(&callFrame
->vm()); 
 719         // This code assumes that if the debugger is enabled then there is no inlining. 
 720         // If that assumption turns out to be false then we'll ignore the inlined call 
 722         // https://bugs.webkit.org/show_bug.cgi?id=121754 
 728             GetExceptionHandlerFunctor functor
; 
 729             callFrame
->iterate(functor
); 
 730             hasHandler 
= !!functor
.handler(); 
 733         debugger
->exception(callFrame
, exceptionValue
, hasHandler
); 
 734         ASSERT(!callFrame
->hadException()); 
 737     // Calculate an exception handler vPC, unwinding call frames as necessary. 
 738     HandlerInfo
* handler 
= 0; 
 739     VM
& vm 
= callFrame
->vm(); 
 740     ASSERT(callFrame 
== vm
.topCallFrame
); 
 741     UnwindFunctor 
functor(callFrame
, isTermination
, codeBlock
, handler
); 
 742     callFrame
->iterate(functor
); 
 746     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
 747         profiler
->exceptionUnwind(callFrame
); 
 749     // Unwind the scope chain within the exception handler's call frame. 
 750     int targetScopeDepth 
= handler
->scopeDepth
; 
 751     if (codeBlock
->needsActivation() && callFrame
->hasActivation()) 
 754     JSScope
* scope 
= callFrame
->scope(); 
 755     int scopeDelta 
= scope
->depth() - targetScopeDepth
; 
 756     RELEASE_ASSERT(scopeDelta 
>= 0); 
 759         scope 
= scope
->next(); 
 760     callFrame
->setScope(scope
); 
 765 static inline JSValue 
checkedReturn(JSValue returnValue
) 
 771 static inline JSObject
* checkedReturn(JSObject
* returnValue
) 
 777 class SamplingScope 
{ 
 779     SamplingScope(Interpreter
* interpreter
) 
 780         : m_interpreter(interpreter
) 
 782         interpreter
->startSampling(); 
 786         m_interpreter
->stopSampling(); 
 789     Interpreter
* m_interpreter
; 
 792 JSValue 
Interpreter::execute(ProgramExecutable
* program
, CallFrame
* callFrame
, JSObject
* thisObj
) 
 794     SamplingScope 
samplingScope(this); 
 796     JSScope
* scope 
= callFrame
->scope(); 
 797     VM
& vm 
= *scope
->vm(); 
 799     ASSERT(!vm
.exception()); 
 800     ASSERT(!vm
.isCollectorBusy()); 
 801     RELEASE_ASSERT(vm
.currentThreadIsHoldingAPILock()); 
 802     if (vm
.isCollectorBusy()) 
 805     if (!vm
.isSafeToRecurse()) 
 806         return checkedReturn(throwStackOverflowError(callFrame
)); 
 808     // First check if the "program" is actually just a JSON object. If so, 
 809     // we'll handle the JSON object here. Else, we'll handle real JS code 
 810     // below at failedJSONP. 
 812     Vector
<JSONPData
> JSONPData
; 
 814     const String programSource 
= program
->source().toString(); 
 815     if (programSource
.isNull()) 
 816         return jsUndefined(); 
 817     if (programSource
.is8Bit()) { 
 818         LiteralParser
<LChar
> literalParser(callFrame
, programSource
.characters8(), programSource
.length(), JSONP
); 
 819         parseResult 
= literalParser
.tryJSONPParse(JSONPData
, scope
->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope
->globalObject())); 
 821         LiteralParser
<UChar
> literalParser(callFrame
, programSource
.characters16(), programSource
.length(), JSONP
); 
 822         parseResult 
= literalParser
.tryJSONPParse(JSONPData
, scope
->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope
->globalObject())); 
 826         JSGlobalObject
* globalObject 
= scope
->globalObject(); 
 828         for (unsigned entry 
= 0; entry 
< JSONPData
.size(); entry
++) { 
 829             Vector
<JSONPPathEntry
> JSONPPath
; 
 830             JSONPPath
.swap(JSONPData
[entry
].m_path
); 
 831             JSValue JSONPValue 
= JSONPData
[entry
].m_value
.get(); 
 832             if (JSONPPath
.size() == 1 && JSONPPath
[0].m_type 
== JSONPPathEntryTypeDeclare
) { 
 833                 globalObject
->addVar(callFrame
, JSONPPath
[0].m_pathEntryName
); 
 834                 PutPropertySlot 
slot(globalObject
); 
 835                 globalObject
->methodTable()->put(globalObject
, callFrame
, JSONPPath
[0].m_pathEntryName
, JSONPValue
, slot
); 
 836                 result 
= jsUndefined(); 
 839             JSValue 
baseObject(globalObject
); 
 840             for (unsigned i 
= 0; i 
< JSONPPath
.size() - 1; i
++) { 
 841                 ASSERT(JSONPPath
[i
].m_type 
!= JSONPPathEntryTypeDeclare
); 
 842                 switch (JSONPPath
[i
].m_type
) { 
 843                 case JSONPPathEntryTypeDot
: { 
 845                         PropertySlot 
slot(globalObject
); 
 846                         if (!globalObject
->getPropertySlot(callFrame
, JSONPPath
[i
].m_pathEntryName
, slot
)) { 
 848                                 return callFrame
->vm().throwException(callFrame
, createUndefinedVariableError(globalObject
->globalExec(), JSONPPath
[i
].m_pathEntryName
)); 
 851                         baseObject 
= slot
.getValue(callFrame
, JSONPPath
[i
].m_pathEntryName
); 
 853                         baseObject 
= baseObject
.get(callFrame
, JSONPPath
[i
].m_pathEntryName
); 
 854                     if (callFrame
->hadException()) 
 855                         return jsUndefined(); 
 858                 case JSONPPathEntryTypeLookup
: { 
 859                     baseObject 
= baseObject
.get(callFrame
, JSONPPath
[i
].m_pathIndex
); 
 860                     if (callFrame
->hadException()) 
 861                         return jsUndefined(); 
 865                     RELEASE_ASSERT_NOT_REACHED(); 
 866                     return jsUndefined(); 
 869             PutPropertySlot 
slot(baseObject
); 
 870             switch (JSONPPath
.last().m_type
) { 
 871             case JSONPPathEntryTypeCall
: { 
 872                 JSValue function 
= baseObject
.get(callFrame
, JSONPPath
.last().m_pathEntryName
); 
 873                 if (callFrame
->hadException()) 
 874                     return jsUndefined(); 
 876                 CallType callType 
= getCallData(function
, callData
); 
 877                 if (callType 
== CallTypeNone
) 
 878                     return callFrame
->vm().throwException(callFrame
, createNotAFunctionError(callFrame
, function
)); 
 879                 MarkedArgumentBuffer jsonArg
; 
 880                 jsonArg
.append(JSONPValue
); 
 881                 JSValue thisValue 
= JSONPPath
.size() == 1 ? jsUndefined(): baseObject
; 
 882                 JSONPValue 
= JSC::call(callFrame
, function
, callType
, callData
, thisValue
, jsonArg
); 
 883                 if (callFrame
->hadException()) 
 884                     return jsUndefined(); 
 887             case JSONPPathEntryTypeDot
: { 
 888                 baseObject
.put(callFrame
, JSONPPath
.last().m_pathEntryName
, JSONPValue
, slot
); 
 889                 if (callFrame
->hadException()) 
 890                     return jsUndefined(); 
 893             case JSONPPathEntryTypeLookup
: { 
 894                 baseObject
.putByIndex(callFrame
, JSONPPath
.last().m_pathIndex
, JSONPValue
, slot
.isStrictMode()); 
 895                 if (callFrame
->hadException()) 
 896                     return jsUndefined(); 
 900                 RELEASE_ASSERT_NOT_REACHED(); 
 901                     return jsUndefined(); 
 908     // If we get here, then we have already proven that the script is not a JSON 
 911     VMEntryScope 
entryScope(vm
, scope
->globalObject()); 
 913     // Compile source to bytecode if necessary: 
 914     if (JSObject
* error 
= program
->initializeGlobalProperties(vm
, callFrame
, scope
)) 
 915         return checkedReturn(callFrame
->vm().throwException(callFrame
, error
)); 
 917     if (JSObject
* error 
= program
->prepareForExecution(callFrame
, nullptr, &scope
, CodeForCall
)) 
 918         return checkedReturn(callFrame
->vm().throwException(callFrame
, error
)); 
 920     ProgramCodeBlock
* codeBlock 
= program
->codeBlock(); 
 922     if (UNLIKELY(vm
.watchdog 
&& vm
.watchdog
->didFire(callFrame
))) 
 923         return throwTerminatedExecutionException(callFrame
); 
 925     ASSERT(codeBlock
->numParameters() == 1); // 1 parameter for 'this'. 
 927     ProtoCallFrame protoCallFrame
; 
 928     protoCallFrame
.init(codeBlock
, scope
, 0, thisObj
, 1); 
 930     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
 931         profiler
->willExecute(callFrame
, program
->sourceURL(), program
->lineNo(), program
->startColumn()); 
 936         SamplingTool::CallRecord 
callRecord(m_sampler
.get()); 
 937         Watchdog::Scope 
watchdogScope(vm
.watchdog
.get()); 
 939         result 
= program
->generatedJITCode()->execute(&vm
, &protoCallFrame
); 
 942     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
 943         profiler
->didExecute(callFrame
, program
->sourceURL(), program
->lineNo(), program
->startColumn()); 
 945     return checkedReturn(result
); 
 948 JSValue 
Interpreter::executeCall(CallFrame
* callFrame
, JSObject
* function
, CallType callType
, const CallData
& callData
, JSValue thisValue
, const ArgList
& args
) 
 950     VM
& vm 
= callFrame
->vm(); 
 951     ASSERT(!callFrame
->hadException()); 
 952     ASSERT(!vm
.isCollectorBusy()); 
 953     if (vm
.isCollectorBusy()) 
 956     bool isJSCall 
= (callType 
== CallTypeJS
); 
 958     CodeBlock
* newCodeBlock
; 
 959     size_t argsCount 
= 1 + args
.size(); // implicit "this" parameter 
 962         scope 
= callData
.js
.scope
; 
 964         ASSERT(callType 
== CallTypeHost
); 
 965         scope 
= callFrame
->scope(); 
 968     VMEntryScope 
entryScope(vm
, scope
->globalObject()); 
 969     if (!vm
.isSafeToRecurse()) 
 970         return checkedReturn(throwStackOverflowError(callFrame
)); 
 973         // Compile the callee: 
 974         JSObject
* compileError 
= callData
.js
.functionExecutable
->prepareForExecution(callFrame
, jsCast
<JSFunction
*>(function
), &scope
, CodeForCall
); 
 975         if (UNLIKELY(!!compileError
)) { 
 976             return checkedReturn(callFrame
->vm().throwException(callFrame
, compileError
)); 
 978         newCodeBlock 
= callData
.js
.functionExecutable
->codeBlockForCall(); 
 979         ASSERT(!!newCodeBlock
); 
 980         newCodeBlock
->m_shouldAlwaysBeInlined 
= false; 
 984     if (UNLIKELY(vm
.watchdog 
&& vm
.watchdog
->didFire(callFrame
))) 
 985         return throwTerminatedExecutionException(callFrame
); 
 987     ProtoCallFrame protoCallFrame
; 
 988     protoCallFrame
.init(newCodeBlock
, scope
, function
, thisValue
, argsCount
, args
.data()); 
 990     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
 991         profiler
->willExecute(callFrame
, function
); 
 995         SamplingTool::CallRecord 
callRecord(m_sampler
.get(), !isJSCall
); 
 996         Watchdog::Scope 
watchdogScope(vm
.watchdog
.get()); 
1000             result 
= callData
.js
.functionExecutable
->generatedJITCodeForCall()->execute(&vm
, &protoCallFrame
); 
1002             result 
= JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData
.native
.function
), &vm
, &protoCallFrame
)); 
1003             if (callFrame
->hadException()) 
1008     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1009         profiler
->didExecute(callFrame
, function
); 
1011     return checkedReturn(result
); 
1014 JSObject
* Interpreter::executeConstruct(CallFrame
* callFrame
, JSObject
* constructor
, ConstructType constructType
, const ConstructData
& constructData
, const ArgList
& args
) 
1016     VM
& vm 
= callFrame
->vm(); 
1017     ASSERT(!callFrame
->hadException()); 
1018     ASSERT(!vm
.isCollectorBusy()); 
1019     // We throw in this case because we have to return something "valid" but we're 
1020     // already in an invalid state. 
1021     if (vm
.isCollectorBusy()) 
1022         return checkedReturn(throwStackOverflowError(callFrame
)); 
1024     bool isJSConstruct 
= (constructType 
== ConstructTypeJS
); 
1026     CodeBlock
* newCodeBlock
; 
1027     size_t argsCount 
= 1 + args
.size(); // implicit "this" parameter 
1030         scope 
= constructData
.js
.scope
; 
1032         ASSERT(constructType 
== ConstructTypeHost
); 
1033         scope 
= callFrame
->scope(); 
1036     VMEntryScope 
entryScope(vm
, scope
->globalObject()); 
1037     if (!vm
.isSafeToRecurse()) 
1038         return checkedReturn(throwStackOverflowError(callFrame
)); 
1040     if (isJSConstruct
) { 
1041         // Compile the callee: 
1042         JSObject
* compileError 
= constructData
.js
.functionExecutable
->prepareForExecution(callFrame
, jsCast
<JSFunction
*>(constructor
), &scope
, CodeForConstruct
); 
1043         if (UNLIKELY(!!compileError
)) { 
1044             return checkedReturn(callFrame
->vm().throwException(callFrame
, compileError
)); 
1046         newCodeBlock 
= constructData
.js
.functionExecutable
->codeBlockForConstruct(); 
1047         ASSERT(!!newCodeBlock
); 
1048         newCodeBlock
->m_shouldAlwaysBeInlined 
= false; 
1052     if (UNLIKELY(vm
.watchdog 
&& vm
.watchdog
->didFire(callFrame
))) 
1053         return throwTerminatedExecutionException(callFrame
); 
1055     ProtoCallFrame protoCallFrame
; 
1056     protoCallFrame
.init(newCodeBlock
, scope
, constructor
, jsUndefined(), argsCount
, args
.data()); 
1058     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1059         profiler
->willExecute(callFrame
, constructor
); 
1063         SamplingTool::CallRecord 
callRecord(m_sampler
.get(), !isJSConstruct
); 
1064         Watchdog::Scope 
watchdogScope(vm
.watchdog
.get()); 
1066         // Execute the code. 
1068             result 
= constructData
.js
.functionExecutable
->generatedJITCodeForConstruct()->execute(&vm
, &protoCallFrame
); 
1070             result 
= JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData
.native
.function
), &vm
, &protoCallFrame
)); 
1072             if (!callFrame
->hadException()) 
1073                 RELEASE_ASSERT(result
.isObject()); 
1077     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1078         profiler
->didExecute(callFrame
, constructor
); 
1080     if (callFrame
->hadException()) 
1082     ASSERT(result
.isObject()); 
1083     return checkedReturn(asObject(result
)); 
1086 CallFrameClosure 
Interpreter::prepareForRepeatCall(FunctionExecutable
* functionExecutable
, CallFrame
* callFrame
, ProtoCallFrame
* protoCallFrame
, JSFunction
* function
, int argumentCountIncludingThis
, JSScope
* scope
, JSValue
* args
) 
1088     VM
& vm 
= *scope
->vm(); 
1089     ASSERT(!vm
.exception()); 
1091     if (vm
.isCollectorBusy()) 
1092         return CallFrameClosure(); 
1094     // Compile the callee: 
1095     JSObject
* error 
= functionExecutable
->prepareForExecution(callFrame
, function
, &scope
, CodeForCall
); 
1097         callFrame
->vm().throwException(callFrame
, error
); 
1098         return CallFrameClosure(); 
1100     CodeBlock
* newCodeBlock 
= functionExecutable
->codeBlockForCall(); 
1101     newCodeBlock
->m_shouldAlwaysBeInlined 
= false; 
1103     size_t argsCount 
= argumentCountIncludingThis
; 
1105     protoCallFrame
->init(newCodeBlock
, scope
, function
, jsUndefined(), argsCount
, args
); 
1106     // Return the successful closure: 
1107     CallFrameClosure result 
= { callFrame
, protoCallFrame
, function
, functionExecutable
, &vm
, scope
, newCodeBlock
->numParameters(), argumentCountIncludingThis 
}; 
1111 JSValue 
Interpreter::execute(CallFrameClosure
& closure
)  
1113     VM
& vm 
= *closure
.vm
; 
1114     SamplingScope 
samplingScope(this); 
1116     ASSERT(!vm
.isCollectorBusy()); 
1117     RELEASE_ASSERT(vm
.currentThreadIsHoldingAPILock()); 
1118     if (vm
.isCollectorBusy()) 
1121     StackStats::CheckPoint stackCheckPoint
; 
1122     closure
.resetCallFrame(); 
1124     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1125         profiler
->willExecute(closure
.oldCallFrame
, closure
.function
); 
1127     if (UNLIKELY(vm
.watchdog 
&& vm
.watchdog
->didFire(closure
.oldCallFrame
))) 
1128         return throwTerminatedExecutionException(closure
.oldCallFrame
); 
1130     // Execute the code: 
1133         SamplingTool::CallRecord 
callRecord(m_sampler
.get()); 
1134         Watchdog::Scope 
watchdogScope(vm
.watchdog
.get()); 
1136         result 
= closure
.functionExecutable
->generatedJITCodeForCall()->execute(&vm
, closure
.protoCallFrame
); 
1139     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1140         profiler
->didExecute(closure
.oldCallFrame
, closure
.function
); 
1142     return checkedReturn(result
); 
1145 JSValue 
Interpreter::execute(EvalExecutable
* eval
, CallFrame
* callFrame
, JSValue thisValue
, JSScope
* scope
) 
1147     VM
& vm 
= *scope
->vm(); 
1148     SamplingScope 
samplingScope(this); 
1150     ASSERT(scope
->vm() == &callFrame
->vm()); 
1151     ASSERT(!vm
.exception()); 
1152     ASSERT(!vm
.isCollectorBusy()); 
1153     RELEASE_ASSERT(vm
.currentThreadIsHoldingAPILock()); 
1154     if (vm
.isCollectorBusy()) 
1157     VMEntryScope 
entryScope(vm
, scope
->globalObject()); 
1158     if (!vm
.isSafeToRecurse()) 
1159         return checkedReturn(throwStackOverflowError(callFrame
));         
1161     unsigned numVariables 
= eval
->numVariables(); 
1162     int numFunctions 
= eval
->numberOfFunctionDecls(); 
1164     JSScope
* variableObject
; 
1165     if ((numVariables 
|| numFunctions
) && eval
->isStrictMode()) { 
1166         scope 
= StrictEvalActivation::create(callFrame
); 
1167         variableObject 
= scope
; 
1169         for (JSScope
* node 
= scope
; ; node 
= node
->next()) { 
1170             RELEASE_ASSERT(node
); 
1171             if (node
->isVariableObject() && !node
->isNameScopeObject()) { 
1172                 variableObject 
= node
; 
1178     JSObject
* compileError 
= eval
->prepareForExecution(callFrame
, nullptr, &scope
, CodeForCall
); 
1179     if (UNLIKELY(!!compileError
)) 
1180         return checkedReturn(callFrame
->vm().throwException(callFrame
, compileError
)); 
1181     EvalCodeBlock
* codeBlock 
= eval
->codeBlock(); 
1183     if (numVariables 
|| numFunctions
) { 
1184         BatchedTransitionOptimizer 
optimizer(vm
, variableObject
); 
1185         if (variableObject
->next()) 
1186             variableObject
->globalObject()->varInjectionWatchpoint()->fireAll(); 
1188         for (unsigned i 
= 0; i 
< numVariables
; ++i
) { 
1189             const Identifier
& ident 
= codeBlock
->variable(i
); 
1190             if (!variableObject
->hasProperty(callFrame
, ident
)) { 
1191                 PutPropertySlot 
slot(variableObject
); 
1192                 variableObject
->methodTable()->put(variableObject
, callFrame
, ident
, jsUndefined(), slot
); 
1196         for (int i 
= 0; i 
< numFunctions
; ++i
) { 
1197             FunctionExecutable
* function 
= codeBlock
->functionDecl(i
); 
1198             PutPropertySlot 
slot(variableObject
); 
1199             variableObject
->methodTable()->put(variableObject
, callFrame
, function
->name(), JSFunction::create(vm
, function
, scope
), slot
); 
1203     if (UNLIKELY(vm
.watchdog 
&& vm
.watchdog
->didFire(callFrame
))) 
1204         return throwTerminatedExecutionException(callFrame
); 
1206     ASSERT(codeBlock
->numParameters() == 1); // 1 parameter for 'this'. 
1208     ProtoCallFrame protoCallFrame
; 
1209     protoCallFrame
.init(codeBlock
, scope
, 0, thisValue
, 1); 
1211     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1212         profiler
->willExecute(callFrame
, eval
->sourceURL(), eval
->lineNo(), eval
->startColumn()); 
1214     // Execute the code: 
1217         SamplingTool::CallRecord 
callRecord(m_sampler
.get()); 
1218         Watchdog::Scope 
watchdogScope(vm
.watchdog
.get()); 
1220         result 
= eval
->generatedJITCode()->execute(&vm
, &protoCallFrame
); 
1223     if (LegacyProfiler
* profiler 
= vm
.enabledProfiler()) 
1224         profiler
->didExecute(callFrame
, eval
->sourceURL(), eval
->lineNo(), eval
->startColumn()); 
1226     return checkedReturn(result
); 
1229 NEVER_INLINE 
void Interpreter::debug(CallFrame
* callFrame
, DebugHookID debugHookID
) 
1231     Debugger
* debugger 
= callFrame
->vmEntryGlobalObject()->debugger(); 
1235     ASSERT(callFrame
->codeBlock()->hasDebuggerRequests()); 
1236     ASSERT(!callFrame
->hadException()); 
1238     switch (debugHookID
) { 
1239         case DidEnterCallFrame
: 
1240             debugger
->callEvent(callFrame
); 
1242         case WillLeaveCallFrame
: 
1243             debugger
->returnEvent(callFrame
); 
1245         case WillExecuteStatement
: 
1246             debugger
->atStatement(callFrame
); 
1248         case WillExecuteProgram
: 
1249             debugger
->willExecuteProgram(callFrame
); 
1251         case DidExecuteProgram
: 
1252             debugger
->didExecuteProgram(callFrame
); 
1254         case DidReachBreakpoint
: 
1255             debugger
->didReachBreakpoint(callFrame
); 
1258     ASSERT(!callFrame
->hadException()); 
1261 void Interpreter::enableSampler() 
1263 #if ENABLE(OPCODE_SAMPLING) 
1265         m_sampler 
= adoptPtr(new SamplingTool(this)); 
1270 void Interpreter::dumpSampleData(ExecState
* exec
) 
1272 #if ENABLE(OPCODE_SAMPLING) 
1274         m_sampler
->dump(exec
); 
1279 void Interpreter::startSampling() 
1281 #if ENABLE(SAMPLING_THREAD) 
1282     if (!m_sampleEntryDepth
) 
1283         SamplingThread::start(); 
1285     m_sampleEntryDepth
++; 
1288 void Interpreter::stopSampling() 
1290 #if ENABLE(SAMPLING_THREAD) 
1291     m_sampleEntryDepth
--; 
1292     if (!m_sampleEntryDepth
) 
1293         SamplingThread::stop();