Rename dataLog() and dataLogV() to dataLogF() and dataLogFV()
[WebKit-https.git] / Source / JavaScriptCore / interpreter / Interpreter.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2012 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 Computer, 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 "CallFrame.h"
36 #include "CallFrameClosure.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 "LiteralParser.h"
56 #include "NameInstance.h"
57 #include "ObjectPrototype.h"
58 #include "Operations.h"
59 #include "Parser.h"
60 #include "Profiler.h"
61 #include "RegExpObject.h"
62 #include "RegExpPrototype.h"
63 #include "Register.h"
64 #include "SamplingTool.h"
65 #include "StrictEvalActivation.h"
66 #include "StrongInlines.h"
67 #include <limits.h>
68 #include <stdio.h>
69 #include <wtf/StackStats.h>
70 #include <wtf/Threading.h>
71 #include <wtf/WTFThreadData.h>
72 #include <wtf/text/StringBuilder.h>
73
74 #if ENABLE(JIT)
75 #include "JIT.h"
76 #endif
77
78 #define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(LLINT) && !defined(__llvm__))
79
80 using namespace std;
81
82 namespace JSC {
83
84 Interpreter::ErrorHandlingMode::ErrorHandlingMode(ExecState *exec)
85     : m_interpreter(*exec->interpreter())
86 {
87     if (!m_interpreter.m_errorHandlingModeReentry)
88         m_interpreter.stack().enableErrorStackReserve();
89     m_interpreter.m_errorHandlingModeReentry++;
90 }
91
92 Interpreter::ErrorHandlingMode::~ErrorHandlingMode()
93 {
94     m_interpreter.m_errorHandlingModeReentry--;
95     ASSERT(m_interpreter.m_errorHandlingModeReentry >= 0);
96     if (!m_interpreter.m_errorHandlingModeReentry)
97         m_interpreter.stack().disableErrorStackReserve();
98 }
99
100
101 // The Interpreter::StackPolicy class is used to compute a stack capacity
102 // requirement to ensure that we have enough room on the native stack for:
103 // 1. the max cumulative stack used by the interpreter and all code
104 //    paths sub of it up till leaf functions.
105 // 2. the max cumulative stack used by the interpreter before it reaches
106 //    the next checkpoint (execute...() function) in the interpreter.
107 // 
108 // The interpreter can be run on different threads and hence, different
109 // native stacks (with different sizes) before exiting out of the first
110 // frame. Hence, the required capacity needs to be re-computed on every
111 // entry into the interpreter.
112 //
113 // Currently the requiredStack is computed based on a policy. See comments
114 // in StackPolicy::StackPolicy() for details.
115
116 Interpreter::StackPolicy::StackPolicy(Interpreter& interpreter, const StackBounds& stack)
117     : m_interpreter(interpreter)
118 {
119     const size_t size = stack.size();
120
121     const size_t DEFAULT_REQUIRED_STACK = 1024 * 1024;
122     const size_t DEFAULT_MINIMUM_USEABLE_STACK = 128 * 1024;
123     const size_t DEFAULT_ERROR_MODE_REQUIRED_STACK = 32 * 1024;
124
125     // Here's the policy in a nutshell:
126     //
127     // 1. If we have a large stack, let JS use as much stack as possible
128     //    but require that we have at least DEFAULT_REQUIRED_STACK capacity
129     //    remaining on the stack:
130     //
131     //    stack grows this way -->   
132     //    ---------------------------------------------------------
133     //    |         ... | <-- DEFAULT_REQUIRED_STACK --> | ...
134     //    ---------------------------------------------------------
135     //    ^             ^
136     //    start         current sp
137     //
138     // 2. In event that we're re-entering the interpreter to handle
139     //    exceptions (in error mode), we'll be a little more generous and
140     //    require less stack capacity for the interpreter to be re-entered.
141     //
142     //    This is needed because we may have just detected an eminent stack
143     //    overflow based on the normally computed required stack capacity.
144     //    However, the normal required capacity far exceeds what is needed
145     //    for exception handling work. Hence, in error mode, we only require
146     //    DEFAULT_ERROR_MODE_REQUIRED_STACK capacity.
147     //
148     //    stack grows this way -->   
149     //    -----------------------------------------------------------------
150     //    |         ... | <-- DEFAULT_ERROR_MODE_REQUIRED_STACK --> | ...
151     //    -----------------------------------------------------------------
152     //    ^             ^
153     //    start         current sp
154     //
155     //    This smaller required capacity also means that we won't re-trigger
156     //    a stack overflow for processing the exception caused by the original
157     //    StackOverflowError.
158     //
159     // 3. If the stack is not large enough, give JS at least a minimum
160     //    amount of useable stack:
161     //
162     //    stack grows this way -->   
163     //    --------------------------------------------------------------------
164     //    | <-- DEFAULT_MINIMUM_USEABLE_STACK --> | <-- requiredCapacity --> |
165     //    --------------------------------------------------------------------
166     //    ^             ^
167     //    start         current sp
168     //
169     //    The minimum useable capacity is DEFAULT_MINIMUM_USEABLE_STACK.
170     //    In this case, the requiredCapacity is whatever is left of the
171     //    total stack capacity after we have give JS its minimum stack
172     //    i.e. requiredCapacity can even be 0 if there's not enough stack.
173
174
175     // Policy 1: Normal mode: required = DEFAULT_REQUIRED_STACK.
176     // Policy 2: Error mode: required = DEFAULT_ERROR_MODE_REQUIRED_STACK.
177     size_t requiredCapacity = !m_interpreter.m_errorHandlingModeReentry ?
178         DEFAULT_REQUIRED_STACK : DEFAULT_ERROR_MODE_REQUIRED_STACK;
179
180     size_t useableStack = (requiredCapacity <= size) ?
181         size - requiredCapacity : DEFAULT_MINIMUM_USEABLE_STACK;
182
183     // Policy 3: Ensure the useable stack is not too small:
184     if (useableStack < DEFAULT_MINIMUM_USEABLE_STACK)
185         useableStack = DEFAULT_MINIMUM_USEABLE_STACK;
186
187     // Sanity check: Make sure we do not use more space than the stack's
188     // total capacity:
189     if (useableStack > size)
190         useableStack = size;
191
192     // Re-compute the requiredCapacity based on the adjusted useable stack
193     // size:
194     requiredCapacity = size - useableStack;
195     ASSERT(requiredCapacity < size);
196
197     m_requiredCapacity = requiredCapacity;    
198 }
199
200
201 static CallFrame* getCallerInfo(JSGlobalData*, CallFrame*, int& lineNumber, unsigned& bytecodeOffset);
202
203 // Returns the depth of the scope chain within a given call frame.
204 static int depth(CodeBlock* codeBlock, JSScope* sc)
205 {
206     if (!codeBlock->needsFullScopeChain())
207         return 0;
208     return sc->localDepth();
209 }
210
211 JSValue eval(CallFrame* callFrame)
212 {
213     if (!callFrame->argumentCount())
214         return jsUndefined();
215
216     JSValue program = callFrame->argument(0);
217     if (!program.isString())
218         return program;
219     
220     TopCallFrameSetter topCallFrame(callFrame->globalData(), callFrame);
221     String programSource = asString(program)->value(callFrame);
222     if (callFrame->hadException())
223         return JSValue();
224     
225     CallFrame* callerFrame = callFrame->callerFrame();
226     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
227     JSScope* callerScopeChain = callerFrame->scope();
228     EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
229
230     if (!eval) {
231         if (!callerCodeBlock->isStrictMode()) {
232             // FIXME: We can use the preparser in strict mode, we just need additional logic
233             // to prevent duplicates.
234             if (programSource.is8Bit()) {
235                 LiteralParser<LChar> preparser(callFrame, programSource.characters8(), programSource.length(), NonStrictJSON);
236                 if (JSValue parsedObject = preparser.tryLiteralParse())
237                     return parsedObject;
238             } else {
239                 LiteralParser<UChar> preparser(callFrame, programSource.characters16(), programSource.length(), NonStrictJSON);
240                 if (JSValue parsedObject = preparser.tryLiteralParse())
241                     return parsedObject;                
242             }
243         }
244         
245         // If the literal parser bailed, it should not have thrown exceptions.
246         ASSERT(!callFrame->globalData().exception);
247
248         JSValue exceptionValue;
249         eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerExecutable(), callerCodeBlock->isStrictMode(), programSource, callerScopeChain, exceptionValue);
250         
251         ASSERT(!eval == exceptionValue);
252         if (UNLIKELY(!eval))
253             return throwError(callFrame, exceptionValue);
254     }
255
256     JSValue thisValue = callerFrame->thisValue();
257     ASSERT(isValidThisObject(thisValue, callFrame));
258     Interpreter* interpreter = callFrame->globalData().interpreter;
259     return interpreter->execute(eval, callFrame, thisValue, callerScopeChain);
260 }
261
262 CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue, JSValue arguments, int firstFreeRegister)
263 {
264     if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
265         unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
266         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
267         if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->grow(newCallFrame->registers())) {
268             callFrame->globalData().exception = createStackOverflowError(callFrame);
269             return 0;
270         }
271
272         newCallFrame->setArgumentCountIncludingThis(argumentCountIncludingThis);
273         newCallFrame->setThisValue(thisValue);
274         for (size_t i = 0; i < callFrame->argumentCount(); ++i)
275             newCallFrame->setArgument(i, callFrame->argumentAfterCapture(i));
276         return newCallFrame;
277     }
278
279     if (arguments.isUndefinedOrNull()) {
280         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + JSStack::CallFrameHeaderSize);
281         if (!stack->grow(newCallFrame->registers())) {
282             callFrame->globalData().exception = createStackOverflowError(callFrame);
283             return 0;
284         }
285         newCallFrame->setArgumentCountIncludingThis(1);
286         newCallFrame->setThisValue(thisValue);
287         return newCallFrame;
288     }
289
290     if (!arguments.isObject()) {
291         callFrame->globalData().exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
292         return 0;
293     }
294
295     if (asObject(arguments)->classInfo() == &Arguments::s_info) {
296         Arguments* argsObject = asArguments(arguments);
297         unsigned argCount = argsObject->length(callFrame);
298         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
299         if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
300             callFrame->globalData().exception = createStackOverflowError(callFrame);
301             return 0;
302         }
303         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
304         newCallFrame->setThisValue(thisValue);
305         argsObject->copyToArguments(callFrame, newCallFrame, argCount);
306         return newCallFrame;
307     }
308
309     if (isJSArray(arguments)) {
310         JSArray* array = asArray(arguments);
311         unsigned argCount = array->length();
312         CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
313         if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
314             callFrame->globalData().exception = createStackOverflowError(callFrame);
315             return 0;
316         }
317         newCallFrame->setArgumentCountIncludingThis(argCount + 1);
318         newCallFrame->setThisValue(thisValue);
319         array->copyToArguments(callFrame, newCallFrame, argCount);
320         return newCallFrame;
321     }
322
323     JSObject* argObject = asObject(arguments);
324     unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
325     CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
326     if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
327         callFrame->globalData().exception = createStackOverflowError(callFrame);
328         return 0;
329     }
330     newCallFrame->setArgumentCountIncludingThis(argCount + 1);
331     newCallFrame->setThisValue(thisValue);
332     for (size_t i = 0; i < argCount; ++i) {
333         newCallFrame->setArgument(i, asObject(arguments)->get(callFrame, i));
334         if (UNLIKELY(callFrame->globalData().exception))
335             return 0;
336     }
337     return newCallFrame;
338 }
339
340 Interpreter::Interpreter(JSGlobalData& globalData)
341     : m_sampleEntryDepth(0)
342     , m_stack(globalData)
343     , m_errorHandlingModeReentry(0)
344 #if !ASSERT_DISABLED
345     , m_initialized(false)
346 #endif
347 {
348 }
349
350 Interpreter::~Interpreter()
351 {
352 }
353
354 void Interpreter::initialize(bool canUseJIT)
355 {
356     UNUSED_PARAM(canUseJIT);
357
358 #if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
359     m_opcodeTable = LLInt::opcodeMap();
360     for (int i = 0; i < numOpcodeIDs; ++i)
361         m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
362 #endif
363
364 #if !ASSERT_DISABLED
365     m_initialized = true;
366 #endif
367
368 #if ENABLE(OPCODE_SAMPLING)
369     enableSampler();
370 #endif
371 }
372
373 #ifdef NDEBUG
374
375 void Interpreter::dumpCallFrame(CallFrame*)
376 {
377 }
378
379 #else
380
381 void Interpreter::dumpCallFrame(CallFrame* callFrame)
382 {
383     callFrame->codeBlock()->dump();
384     dumpRegisters(callFrame);
385 }
386
387 void Interpreter::dumpRegisters(CallFrame* callFrame)
388 {
389     dataLogF("Register frame: \n\n");
390     dataLogF("-----------------------------------------------------------------------------\n");
391     dataLogF("            use            |   address  |                value               \n");
392     dataLogF("-----------------------------------------------------------------------------\n");
393
394     CodeBlock* codeBlock = callFrame->codeBlock();
395     const Register* it;
396     const Register* end;
397
398     it = callFrame->registers() - JSStack::CallFrameHeaderSize - callFrame->argumentCountIncludingThis();
399     end = callFrame->registers() - JSStack::CallFrameHeaderSize;
400     while (it < end) {
401         JSValue v = it->jsValue();
402         int registerNumber = it - callFrame->registers();
403         String name = codeBlock->nameForRegister(registerNumber);
404         dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, v.description(), (long long)JSValue::encode(v));
405         it++;
406     }
407     
408     dataLogF("-----------------------------------------------------------------------------\n");
409     dataLogF("[ArgumentCount]            | %10p | %lu \n", it, (unsigned long) callFrame->argumentCount());
410     ++it;
411     dataLogF("[CallerFrame]              | %10p | %p \n", it, callFrame->callerFrame());
412     ++it;
413     dataLogF("[Callee]                   | %10p | %p \n", it, callFrame->callee());
414     ++it;
415     dataLogF("[ScopeChain]               | %10p | %p \n", it, callFrame->scope());
416     ++it;
417 #if ENABLE(JIT)
418     AbstractPC pc = callFrame->abstractReturnPC(callFrame->globalData());
419     if (pc.hasJITReturnAddress())
420         dataLogF("[ReturnJITPC]              | %10p | %p \n", it, pc.jitReturnAddress().value());
421 #endif
422     unsigned bytecodeOffset = 0;
423     int line = 0;
424     getCallerInfo(&callFrame->globalData(), callFrame, line, bytecodeOffset);
425     dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", it, bytecodeOffset, line);
426     ++it;
427     dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
428     ++it;
429     dataLogF("-----------------------------------------------------------------------------\n");
430
431     int registerCount = 0;
432
433     end = it + codeBlock->m_numVars;
434     if (it != end) {
435         do {
436             JSValue v = it->jsValue();
437             int registerNumber = it - callFrame->registers();
438             String name = codeBlock->nameForRegister(registerNumber);
439             dataLogF("[r% 3d %14s]      | %10p | %-16s 0x%lld \n", registerNumber, name.ascii().data(), it, v.description(), (long long)JSValue::encode(v));
440             ++it;
441             ++registerCount;
442         } while (it != end);
443     }
444     dataLogF("-----------------------------------------------------------------------------\n");
445
446     end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars;
447     if (it != end) {
448         do {
449             JSValue v = (*it).jsValue();
450             dataLogF("[r% 3d]                     | %10p | %-16s 0x%lld \n", registerCount, it, v.description(), (long long)JSValue::encode(v));
451             ++it;
452             ++registerCount;
453         } while (it != end);
454     }
455     dataLogF("-----------------------------------------------------------------------------\n");
456 }
457
458 #endif
459
460 bool Interpreter::isOpcode(Opcode opcode)
461 {
462 #if ENABLE(COMPUTED_GOTO_OPCODES)
463 #if !ENABLE(LLINT)
464     return static_cast<OpcodeID>(bitwise_cast<uintptr_t>(opcode)) <= op_end;
465 #else
466     return opcode != HashTraits<Opcode>::emptyValue()
467         && !HashTraits<Opcode>::isDeletedValue(opcode)
468         && m_opcodeIDTable.contains(opcode);
469 #endif
470 #else
471     return opcode >= 0 && opcode <= op_end;
472 #endif
473 }
474
475 NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock)
476 {
477     CodeBlock* oldCodeBlock = codeBlock;
478     JSScope* scope = callFrame->scope();
479
480     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
481         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
482         if (callFrame->callee())
483             debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine(), 0);
484         else
485             debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine(), 0);
486     }
487
488     JSValue activation;
489     if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsActivation()) {
490         activation = callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue();
491         if (activation)
492             jsCast<JSActivation*>(activation)->tearOff(*scope->globalData());
493     }
494
495     if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->usesArguments()) {
496         if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
497             if (activation)
498                 jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
499             else
500                 jsCast<Arguments*>(arguments)->tearOff(callFrame);
501         }
502     }
503
504     CallFrame* callerFrame = callFrame->callerFrame();
505     callFrame->globalData().topCallFrame = callerFrame;
506     if (callerFrame->hasHostCallFrameFlag())
507         return false;
508
509     codeBlock = callerFrame->codeBlock();
510     
511     // Because of how the JIT records call site->bytecode offset
512     // information the JIT reports the bytecodeOffset for the returnPC
513     // to be at the beginning of the opcode that has caused the call.
514 #if ENABLE(JIT) || ENABLE(LLINT)
515     bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
516 #endif
517
518     callFrame = callerFrame;
519     return true;
520 }
521
522 static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset)
523 {
524     exception->clearAppendSourceToMessage();
525
526     if (!callFrame->codeBlock()->hasExpressionInfo())
527         return;
528
529     int startOffset = 0;
530     int endOffset = 0;
531     int divotPoint = 0;
532
533     CodeBlock* codeBlock = callFrame->codeBlock();
534     codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset);
535
536     int expressionStart = divotPoint - startOffset;
537     int expressionStop = divotPoint + endOffset;
538
539     const String& sourceString = codeBlock->source()->source();
540     if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
541         return;
542
543     JSGlobalData* globalData = &callFrame->globalData();
544     JSValue jsMessage = exception->getDirect(*globalData, globalData->propertyNames->message);
545     if (!jsMessage || !jsMessage.isString())
546         return;
547
548     String message = asString(jsMessage)->value(callFrame);
549
550     if (expressionStart < expressionStop)
551         message =  makeString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')");
552     else {
553         // No range information, so give a few characters of context
554         const StringImpl* data = sourceString.impl();
555         int dataLength = sourceString.length();
556         int start = expressionStart;
557         int stop = expressionStart;
558         // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
559         // then strip whitespace.
560         while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
561             start--;
562         while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
563             start++;
564         while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
565             stop++;
566         while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
567             stop--;
568         message = makeString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
569     }
570
571     exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message));
572 }
573
574 static int getLineNumberForCallFrame(JSGlobalData* globalData, CallFrame* callFrame)
575 {
576     UNUSED_PARAM(globalData);
577     callFrame = callFrame->removeHostCallFrameFlag();
578     CodeBlock* codeBlock = callFrame->codeBlock();
579     if (!codeBlock)
580         return -1;
581 #if ENABLE(JIT) || ENABLE(LLINT)
582 #if ENABLE(DFG_JIT)
583     if (codeBlock->getJITType() == JITCode::DFGJIT)
584         return codeBlock->lineNumberForBytecodeOffset(codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex);
585 #endif
586     return codeBlock->lineNumberForBytecodeOffset(callFrame->bytecodeOffsetForNonDFGCode());
587 #endif
588 }
589
590 static CallFrame* getCallerInfo(JSGlobalData* globalData, CallFrame* callFrame, int& lineNumber, unsigned& bytecodeOffset)
591 {
592     UNUSED_PARAM(globalData);
593     bytecodeOffset = 0;
594     lineNumber = -1;
595     ASSERT(!callFrame->hasHostCallFrameFlag());
596     CallFrame* callerFrame = callFrame->codeBlock() ? callFrame->trueCallerFrame() : callFrame->callerFrame()->removeHostCallFrameFlag();
597     bool callframeIsHost = callerFrame->addHostCallFrameFlag() == callFrame->callerFrame();
598     ASSERT(!callerFrame->hasHostCallFrameFlag());
599
600     if (callerFrame == CallFrame::noCaller() || !callerFrame || !callerFrame->codeBlock())
601         return callerFrame;
602     
603     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
604     
605 #if ENABLE(JIT) || ENABLE(LLINT)
606     if (!callFrame->hasReturnPC())
607         callframeIsHost = true;
608 #endif
609 #if ENABLE(DFG_JIT)
610     if (callFrame->isInlineCallFrame())
611         callframeIsHost = false;
612 #endif
613
614     if (callframeIsHost) {
615         // Don't need to deal with inline callframes here as by definition we haven't
616         // inlined a call with an intervening native call frame.
617 #if ENABLE(JIT) || ENABLE(LLINT)
618 #if ENABLE(DFG_JIT)
619         if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
620             unsigned codeOriginIndex = callerFrame->codeOriginIndexForDFG();
621             bytecodeOffset = callerCodeBlock->codeOrigin(codeOriginIndex).bytecodeIndex;
622         } else
623 #endif
624             bytecodeOffset = callerFrame->bytecodeOffsetForNonDFGCode();
625 #endif
626     } else {
627 #if ENABLE(JIT) || ENABLE(LLINT)
628     #if ENABLE(DFG_JIT)
629         if (callFrame->isInlineCallFrame()) {
630             InlineCallFrame* icf = callFrame->inlineCallFrame();
631             bytecodeOffset = icf->caller.bytecodeIndex;
632             if (InlineCallFrame* parentCallFrame = icf->caller.inlineCallFrame) {
633                 FunctionExecutable* executable = static_cast<FunctionExecutable*>(parentCallFrame->executable.get());
634                 CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(parentCallFrame->isCall ? CodeForCall : CodeForConstruct);
635                 ASSERT(newCodeBlock);
636                 ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
637                 callerCodeBlock = newCodeBlock;
638             }
639         } else if (callerCodeBlock && callerCodeBlock->getJITType() == JITCode::DFGJIT) {
640             CodeOrigin origin;
641             if (!callerCodeBlock->codeOriginForReturn(callFrame->returnPC(), origin))
642                 ASSERT_NOT_REACHED();
643             bytecodeOffset = origin.bytecodeIndex;
644             if (InlineCallFrame* icf = origin.inlineCallFrame) {
645                 FunctionExecutable* executable = static_cast<FunctionExecutable*>(icf->executable.get());
646                 CodeBlock* newCodeBlock = executable->baselineCodeBlockFor(icf->isCall ? CodeForCall : CodeForConstruct);
647                 ASSERT(newCodeBlock);
648                 ASSERT(newCodeBlock->instructionCount() > bytecodeOffset);
649                 callerCodeBlock = newCodeBlock;
650             }
651         } else
652     #endif
653             bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
654 #endif
655     }
656
657     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset);
658     return callerFrame;
659 }
660
661 static ALWAYS_INLINE const String getSourceURLFromCallFrame(CallFrame* callFrame)
662 {
663     ASSERT(!callFrame->hasHostCallFrameFlag());
664     return callFrame->codeBlock()->ownerExecutable()->sourceURL();
665 }
666
667 static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame)
668 {
669     ASSERT(!callFrame->hasHostCallFrameFlag());
670
671     switch (callFrame->codeBlock()->codeType()) {
672     case EvalCode:
673         return StackFrameEvalCode;
674     case FunctionCode:
675         return StackFrameFunctionCode;
676     case GlobalCode:
677         return StackFrameGlobalCode;
678     }
679     ASSERT_NOT_REACHED();
680     return StackFrameGlobalCode;
681 }
682
683 void Interpreter::getStackTrace(JSGlobalData* globalData, Vector<StackFrame>& results)
684 {
685     CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag();
686     if (!callFrame || callFrame == CallFrame::noCaller()) 
687         return;
688     int line = getLineNumberForCallFrame(globalData, callFrame);
689
690     callFrame = callFrame->trueCallFrameFromVMCode();
691
692     while (callFrame && callFrame != CallFrame::noCaller()) {
693         String sourceURL;
694         if (callFrame->codeBlock()) {
695             sourceURL = getSourceURLFromCallFrame(callFrame);
696             StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), getStackFrameCodeType(callFrame), Strong<ExecutableBase>(*globalData, callFrame->codeBlock()->ownerExecutable()), line, sourceURL};
697             results.append(s);
698         } else {
699             StackFrame s = { Strong<JSObject>(*globalData, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), -1, String()};
700             results.append(s);
701         }
702         unsigned unusedBytecodeOffset = 0;
703         callFrame = getCallerInfo(globalData, callFrame, line, unusedBytecodeOffset);
704     }
705 }
706
707 void Interpreter::addStackTraceIfNecessary(CallFrame* callFrame, JSObject* error)
708 {
709     JSGlobalData* globalData = &callFrame->globalData();
710     ASSERT(callFrame == globalData->topCallFrame || callFrame == callFrame->lexicalGlobalObject()->globalExec() || callFrame == callFrame->dynamicGlobalObject()->globalExec());
711     if (error->hasProperty(callFrame, globalData->propertyNames->stack))
712         return;
713
714     Vector<StackFrame> stackTrace;
715     getStackTrace(&callFrame->globalData(), stackTrace);
716     
717     if (stackTrace.isEmpty())
718         return;
719     
720     JSGlobalObject* globalObject = 0;
721     if (isTerminatedExecutionException(error) || isInterruptedExecutionException(error))
722         globalObject = globalData->dynamicGlobalObject;
723     else
724         globalObject = error->globalObject();
725
726     // FIXME: JSStringJoiner could be more efficient than StringBuilder here.
727     StringBuilder builder;
728     for (unsigned i = 0; i < stackTrace.size(); i++) {
729         builder.append(String(stackTrace[i].toString(globalObject->globalExec()).impl()));
730         if (i != stackTrace.size() - 1)
731             builder.append('\n');
732     }
733     
734     error->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, builder.toString()), ReadOnly | DontDelete);
735 }
736
737 NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
738 {
739     CodeBlock* codeBlock = callFrame->codeBlock();
740     bool isInterrupt = false;
741
742     ASSERT(!exceptionValue.isEmpty());
743     ASSERT(!exceptionValue.isCell() || exceptionValue.asCell());
744     // This shouldn't be possible (hence the assertions), but we're already in the slowest of
745     // slow cases, so let's harden against it anyway to be safe.
746     if (exceptionValue.isEmpty() || (exceptionValue.isCell() && !exceptionValue.asCell()))
747         exceptionValue = jsNull();
748
749     // Set up the exception object
750     if (exceptionValue.isObject()) {
751         JSObject* exception = asObject(exceptionValue);
752
753         if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage())
754             appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
755
756         if (!hasErrorInfo(callFrame, exception)) {
757             // FIXME: should only really be adding these properties to VM generated exceptions,
758             // but the inspector currently requires these for all thrown objects.
759             addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source());
760         }
761
762         isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception);
763     }
764
765     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
766         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
767         bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
768         debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), 0, hasHandler);
769     }
770
771     // Calculate an exception handler vPC, unwinding call frames as necessary.
772     HandlerInfo* handler = 0;
773     while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
774         if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
775             if (Profiler* profiler = callFrame->globalData().enabledProfiler())
776                 profiler->exceptionUnwind(callFrame);
777             return 0;
778         }
779     }
780
781     if (Profiler* profiler = callFrame->globalData().enabledProfiler())
782         profiler->exceptionUnwind(callFrame);
783
784     // Unwind the scope chain within the exception handler's call frame.
785     JSScope* scope = callFrame->scope();
786     int scopeDelta = 0;
787     if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode 
788         || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
789         scopeDelta = depth(codeBlock, scope) - handler->scopeDepth;
790     ASSERT(scopeDelta >= 0);
791     while (scopeDelta--)
792         scope = scope->next();
793     callFrame->setScope(scope);
794
795     return handler;
796 }
797
798 static inline JSValue checkedReturn(JSValue returnValue)
799 {
800     ASSERT(returnValue);
801     return returnValue;
802 }
803
804 static inline JSObject* checkedReturn(JSObject* returnValue)
805 {
806     ASSERT(returnValue);
807     return returnValue;
808 }
809
810 class SamplingScope {
811 public:
812     SamplingScope(Interpreter* interpreter)
813         : m_interpreter(interpreter)
814     {
815         interpreter->startSampling();
816     }
817     ~SamplingScope()
818     {
819         m_interpreter->stopSampling();
820     }
821 private:
822     Interpreter* m_interpreter;
823 };
824
825 JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
826 {
827     SamplingScope samplingScope(this);
828     
829     JSScope* scope = callFrame->scope();
830     JSGlobalData& globalData = *scope->globalData();
831
832     ASSERT(isValidThisObject(thisObj, callFrame));
833     ASSERT(!globalData.exception);
834     ASSERT(!globalData.isCollectorBusy());
835     if (globalData.isCollectorBusy())
836         CRASH();
837
838     StackStats::CheckPoint stackCheckPoint;
839     const StackBounds& nativeStack = wtfThreadData().stack();
840     StackPolicy policy(*this, nativeStack);
841     if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
842         return checkedReturn(throwStackOverflowError(callFrame));
843
844     // First check if the "program" is actually just a JSON object. If so,
845     // we'll handle the JSON object here. Else, we'll handle real JS code
846     // below at failedJSONP.
847     DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
848     Vector<JSONPData> JSONPData;
849     bool parseResult;
850     const String programSource = program->source().toString();
851     if (programSource.isNull())
852         return jsUndefined();
853     if (programSource.is8Bit()) {
854         LiteralParser<LChar> literalParser(callFrame, programSource.characters8(), programSource.length(), JSONP);
855         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
856     } else {
857         LiteralParser<UChar> literalParser(callFrame, programSource.characters16(), programSource.length(), JSONP);
858         parseResult = literalParser.tryJSONPParse(JSONPData, scope->globalObject()->globalObjectMethodTable()->supportsRichSourceInfo(scope->globalObject()));
859     }
860
861     if (parseResult) {
862         JSGlobalObject* globalObject = scope->globalObject();
863         JSValue result;
864         for (unsigned entry = 0; entry < JSONPData.size(); entry++) {
865             Vector<JSONPPathEntry> JSONPPath;
866             JSONPPath.swap(JSONPData[entry].m_path);
867             JSValue JSONPValue = JSONPData[entry].m_value.get();
868             if (JSONPPath.size() == 1 && JSONPPath[0].m_type == JSONPPathEntryTypeDeclare) {
869                 if (globalObject->hasProperty(callFrame, JSONPPath[0].m_pathEntryName)) {
870                     PutPropertySlot slot;
871                     globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
872                 } else
873                     globalObject->methodTable()->putDirectVirtual(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, DontEnum | DontDelete);
874                 // var declarations return undefined
875                 result = jsUndefined();
876                 continue;
877             }
878             JSValue baseObject(globalObject);
879             for (unsigned i = 0; i < JSONPPath.size() - 1; i++) {
880                 ASSERT(JSONPPath[i].m_type != JSONPPathEntryTypeDeclare);
881                 switch (JSONPPath[i].m_type) {
882                 case JSONPPathEntryTypeDot: {
883                     if (i == 0) {
884                         PropertySlot slot(globalObject);
885                         if (!globalObject->getPropertySlot(callFrame, JSONPPath[i].m_pathEntryName, slot)) {
886                             if (entry)
887                                 return throwError(callFrame, createUndefinedVariableError(globalObject->globalExec(), JSONPPath[i].m_pathEntryName));
888                             goto failedJSONP;
889                         }
890                         baseObject = slot.getValue(callFrame, JSONPPath[i].m_pathEntryName);
891                     } else
892                         baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathEntryName);
893                     if (callFrame->hadException())
894                         return jsUndefined();
895                     continue;
896                 }
897                 case JSONPPathEntryTypeLookup: {
898                     baseObject = baseObject.get(callFrame, JSONPPath[i].m_pathIndex);
899                     if (callFrame->hadException())
900                         return jsUndefined();
901                     continue;
902                 }
903                 default:
904                     ASSERT_NOT_REACHED();
905                     return jsUndefined();
906                 }
907             }
908             PutPropertySlot slot;
909             switch (JSONPPath.last().m_type) {
910             case JSONPPathEntryTypeCall: {
911                 JSValue function = baseObject.get(callFrame, JSONPPath.last().m_pathEntryName);
912                 if (callFrame->hadException())
913                     return jsUndefined();
914                 CallData callData;
915                 CallType callType = getCallData(function, callData);
916                 if (callType == CallTypeNone)
917                     return throwError(callFrame, createNotAFunctionError(callFrame, function));
918                 MarkedArgumentBuffer jsonArg;
919                 jsonArg.append(JSONPValue);
920                 JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
921                 JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
922                 if (callFrame->hadException())
923                     return jsUndefined();
924                 break;
925             }
926             case JSONPPathEntryTypeDot: {
927                 baseObject.put(callFrame, JSONPPath.last().m_pathEntryName, JSONPValue, slot);
928                 if (callFrame->hadException())
929                     return jsUndefined();
930                 break;
931             }
932             case JSONPPathEntryTypeLookup: {
933                 baseObject.putByIndex(callFrame, JSONPPath.last().m_pathIndex, JSONPValue, slot.isStrictMode());
934                 if (callFrame->hadException())
935                     return jsUndefined();
936                 break;
937             }
938             default:
939                 ASSERT_NOT_REACHED();
940                     return jsUndefined();
941             }
942             result = JSONPValue;
943         }
944         return result;
945     }
946 failedJSONP:
947     // If we get here, then we have already proven that the script is not a JSON
948     // object.
949
950     // Compile source to bytecode if necessary:
951     if (JSObject* error = program->initalizeGlobalProperties(globalData, callFrame, scope))
952         return checkedReturn(throwError(callFrame, error));
953
954     if (JSObject* error = program->compile(callFrame, scope))
955         return checkedReturn(throwError(callFrame, error));
956
957     ProgramCodeBlock* codeBlock = &program->generatedBytecode();
958
959     // Push the call frame for this invocation:
960     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
961     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
962     if (UNLIKELY(!newCallFrame))
963         return checkedReturn(throwStackOverflowError(callFrame));
964
965     // Set the arguments for the callee:
966     newCallFrame->setThisValue(thisObj);
967
968     if (Profiler* profiler = globalData.enabledProfiler())
969         profiler->willExecute(callFrame, program->sourceURL(), program->lineNo());
970
971     // Execute the code:
972     JSValue result;
973     {
974         SamplingTool::CallRecord callRecord(m_sampler.get());
975
976 #if ENABLE(LLINT_C_LOOP)
977         result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
978 #elif ENABLE(JIT)
979         result = program->generatedJITCode().execute(&m_stack, newCallFrame, &globalData);
980 #endif // ENABLE(JIT)
981     }
982
983     if (Profiler* profiler = globalData.enabledProfiler())
984         profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
985
986     m_stack.popFrame(newCallFrame);
987
988     return checkedReturn(result);
989 }
990
991 JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
992 {
993     JSGlobalData& globalData = callFrame->globalData();
994     ASSERT(isValidThisObject(thisValue, callFrame));
995     ASSERT(!callFrame->hadException());
996     ASSERT(!globalData.isCollectorBusy());
997     if (globalData.isCollectorBusy())
998         return jsNull();
999
1000     StackStats::CheckPoint stackCheckPoint;
1001     const StackBounds& nativeStack = wtfThreadData().stack();
1002     StackPolicy policy(*this, nativeStack);
1003     if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
1004         return checkedReturn(throwStackOverflowError(callFrame));
1005
1006     bool isJSCall = (callType == CallTypeJS);
1007     JSScope* scope;
1008     CodeBlock* newCodeBlock;
1009     size_t argsCount = 1 + args.size(); // implicit "this" parameter
1010
1011     if (isJSCall)
1012         scope = callData.js.scope;
1013     else {
1014         ASSERT(callType == CallTypeHost);
1015         scope = callFrame->scope();
1016     }
1017     DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
1018
1019     if (isJSCall) {
1020         // Compile the callee:
1021         JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, scope);
1022         if (UNLIKELY(!!compileError)) {
1023             return checkedReturn(throwError(callFrame, compileError));
1024         }
1025         newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
1026         ASSERT(!!newCodeBlock);
1027     } else
1028         newCodeBlock = 0;
1029
1030     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
1031     if (UNLIKELY(!newCallFrame))
1032         return checkedReturn(throwStackOverflowError(callFrame));
1033
1034     // Set the arguments for the callee:
1035     newCallFrame->setThisValue(thisValue);
1036     for (size_t i = 0; i < args.size(); ++i)
1037         newCallFrame->setArgument(i, args.at(i));
1038
1039     if (Profiler* profiler = globalData.enabledProfiler())
1040         profiler->willExecute(callFrame, function);
1041
1042     JSValue result;
1043     {
1044         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSCall);
1045
1046         // Execute the code:
1047         if (isJSCall) {
1048 #if ENABLE(LLINT_C_LOOP)
1049             result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
1050 #elif ENABLE(JIT)
1051             result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_stack, newCallFrame, &globalData);
1052 #endif // ENABLE(JIT)
1053         } else
1054             result = JSValue::decode(callData.native.function(newCallFrame));
1055     }
1056
1057     if (Profiler* profiler = globalData.enabledProfiler())
1058         profiler->didExecute(callFrame, function);
1059
1060     m_stack.popFrame(newCallFrame);
1061     return checkedReturn(result);
1062 }
1063
1064 JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
1065 {
1066     JSGlobalData& globalData = callFrame->globalData();
1067     ASSERT(!callFrame->hadException());
1068     ASSERT(!globalData.isCollectorBusy());
1069     // We throw in this case because we have to return something "valid" but we're
1070     // already in an invalid state.
1071     if (globalData.isCollectorBusy())
1072         return checkedReturn(throwStackOverflowError(callFrame));
1073
1074     StackStats::CheckPoint stackCheckPoint;
1075     const StackBounds& nativeStack = wtfThreadData().stack();
1076     StackPolicy policy(*this, nativeStack);
1077     if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
1078         return checkedReturn(throwStackOverflowError(callFrame));
1079
1080     bool isJSConstruct = (constructType == ConstructTypeJS);
1081     JSScope* scope;
1082     CodeBlock* newCodeBlock;
1083     size_t argsCount = 1 + args.size(); // implicit "this" parameter
1084
1085     if (isJSConstruct)
1086         scope = constructData.js.scope;
1087     else {
1088         ASSERT(constructType == ConstructTypeHost);
1089         scope = callFrame->scope();
1090     }
1091
1092     DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
1093
1094     if (isJSConstruct) {
1095         // Compile the callee:
1096         JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, scope);
1097         if (UNLIKELY(!!compileError)) {
1098             return checkedReturn(throwError(callFrame, compileError));
1099         }
1100         newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
1101         ASSERT(!!newCodeBlock);
1102     } else
1103         newCodeBlock = 0;
1104
1105     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, constructor);
1106     if (UNLIKELY(!newCallFrame))
1107         return checkedReturn(throwStackOverflowError(callFrame));
1108
1109     // Set the arguments for the callee:
1110     newCallFrame->setThisValue(jsUndefined());
1111     for (size_t i = 0; i < args.size(); ++i)
1112         newCallFrame->setArgument(i, args.at(i));
1113
1114     if (Profiler* profiler = globalData.enabledProfiler())
1115         profiler->willExecute(callFrame, constructor);
1116
1117     JSValue result;
1118     {
1119         SamplingTool::CallRecord callRecord(m_sampler.get(), !isJSConstruct);
1120
1121         // Execute the code.
1122         if (isJSConstruct) {
1123 #if ENABLE(LLINT_C_LOOP)
1124             result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
1125 #elif ENABLE(JIT)
1126             result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_stack, newCallFrame, &globalData);
1127 #endif // ENABLE(JIT)
1128         } else {
1129             result = JSValue::decode(constructData.native.function(newCallFrame));
1130         }
1131     }
1132
1133     if (Profiler* profiler = globalData.enabledProfiler())
1134         profiler->didExecute(callFrame, constructor);
1135
1136     m_stack.popFrame(newCallFrame);
1137
1138     if (callFrame->hadException())
1139         return 0;
1140     ASSERT(result.isObject());
1141     return checkedReturn(asObject(result));
1142 }
1143
1144 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
1145 {
1146     JSGlobalData& globalData = *scope->globalData();
1147     ASSERT(!globalData.exception);
1148     
1149     if (globalData.isCollectorBusy())
1150         return CallFrameClosure();
1151
1152     StackStats::CheckPoint stackCheckPoint;
1153     const StackBounds& nativeStack = wtfThreadData().stack();
1154     StackPolicy policy(*this, nativeStack);
1155     if (!nativeStack.isSafeToRecurse(policy.requiredCapacity())) {
1156         throwStackOverflowError(callFrame);
1157         return CallFrameClosure();
1158     }
1159
1160     // Compile the callee:
1161     JSObject* error = functionExecutable->compileForCall(callFrame, scope);
1162     if (error) {
1163         throwError(callFrame, error);
1164         return CallFrameClosure();
1165     }
1166     CodeBlock* newCodeBlock = &functionExecutable->generatedBytecodeForCall();
1167
1168     size_t argsCount = argumentCountIncludingThis;
1169
1170     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);  
1171     if (UNLIKELY(!newCallFrame)) {
1172         throwStackOverflowError(callFrame);
1173         return CallFrameClosure();
1174     }
1175
1176     if (UNLIKELY(!newCallFrame)) {
1177         throwStackOverflowError(callFrame);
1178         return CallFrameClosure();
1179     }
1180
1181     // Return the successful closure:
1182     CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &globalData, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
1183     return result;
1184 }
1185
1186 JSValue Interpreter::execute(CallFrameClosure& closure) 
1187 {
1188     JSGlobalData& globalData = *closure.globalData;
1189     SamplingScope samplingScope(this);
1190     
1191     ASSERT(!globalData.isCollectorBusy());
1192     if (globalData.isCollectorBusy())
1193         return jsNull();
1194
1195     StackStats::CheckPoint stackCheckPoint;
1196     m_stack.validateFence(closure.newCallFrame, "BEFORE");
1197     closure.resetCallFrame();
1198     m_stack.validateFence(closure.newCallFrame, "STEP 1");
1199
1200     if (Profiler* profiler = globalData.enabledProfiler())
1201         profiler->willExecute(closure.oldCallFrame, closure.function);
1202
1203     // The code execution below may push more frames and point the topCallFrame
1204     // to those newer frames, or it may pop to the top frame to the caller of
1205     // the current repeat frame, or it may leave the top frame pointing to the
1206     // current repeat frame.
1207     //
1208     // Hence, we need to preserve the topCallFrame here ourselves before
1209     // repeating this call on a second callback function.
1210
1211     TopCallFrameSetter topCallFrame(globalData, closure.newCallFrame);
1212
1213     // Execute the code:
1214     JSValue result;
1215     {
1216         SamplingTool::CallRecord callRecord(m_sampler.get());
1217         
1218 #if ENABLE(LLINT_C_LOOP)
1219         result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
1220 #elif ENABLE(JIT)
1221         result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_stack, closure.newCallFrame, &globalData);
1222 #endif // ENABLE(JIT)
1223     }
1224
1225     if (Profiler* profiler = globalData.enabledProfiler())
1226         profiler->didExecute(closure.oldCallFrame, closure.function);
1227
1228     m_stack.validateFence(closure.newCallFrame, "AFTER");
1229     return checkedReturn(result);
1230 }
1231
1232 void Interpreter::endRepeatCall(CallFrameClosure& closure)
1233 {
1234     m_stack.popFrame(closure.newCallFrame);
1235 }
1236
1237 JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
1238 {
1239     JSGlobalData& globalData = *scope->globalData();
1240     SamplingScope samplingScope(this);
1241     
1242     ASSERT(scope->globalData() == &callFrame->globalData());
1243     ASSERT(isValidThisObject(thisValue, callFrame));
1244     ASSERT(!globalData.exception);
1245     ASSERT(!globalData.isCollectorBusy());
1246     if (globalData.isCollectorBusy())
1247         return jsNull();
1248
1249     DynamicGlobalObjectScope globalObjectScope(globalData, scope->globalObject());
1250
1251     StackStats::CheckPoint stackCheckPoint;
1252     const StackBounds& nativeStack = wtfThreadData().stack();
1253     StackPolicy policy(*this, nativeStack);
1254     if (!nativeStack.isSafeToRecurse(policy.requiredCapacity()))
1255         return checkedReturn(throwStackOverflowError(callFrame));
1256
1257     // Compile the callee:
1258     JSObject* compileError = eval->compile(callFrame, scope);
1259     if (UNLIKELY(!!compileError))
1260         return checkedReturn(throwError(callFrame, compileError));
1261     EvalCodeBlock* codeBlock = &eval->generatedBytecode();
1262
1263     JSObject* variableObject;
1264     for (JSScope* node = scope; ; node = node->next()) {
1265         ASSERT(node);
1266         if (node->isVariableObject() && !node->isNameScopeObject()) {
1267             variableObject = node;
1268             break;
1269         }
1270     }
1271
1272     unsigned numVariables = codeBlock->numVariables();
1273     int numFunctions = codeBlock->numberOfFunctionDecls();
1274     if (numVariables || numFunctions) {
1275         if (codeBlock->isStrictMode()) {
1276             scope = StrictEvalActivation::create(callFrame);
1277             variableObject = scope;
1278         }
1279         // Scope for BatchedTransitionOptimizer
1280         BatchedTransitionOptimizer optimizer(globalData, variableObject);
1281
1282         for (unsigned i = 0; i < numVariables; ++i) {
1283             const Identifier& ident = codeBlock->variable(i);
1284             if (!variableObject->hasProperty(callFrame, ident)) {
1285                 PutPropertySlot slot;
1286                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
1287             }
1288         }
1289
1290         for (int i = 0; i < numFunctions; ++i) {
1291             FunctionExecutable* function = codeBlock->functionDecl(i);
1292             PutPropertySlot slot;
1293             variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(callFrame, function, scope), slot);
1294         }
1295     }
1296
1297     // Push the frame:
1298     ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
1299     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
1300     if (UNLIKELY(!newCallFrame))
1301         return checkedReturn(throwStackOverflowError(callFrame));
1302
1303     // Set the arguments for the callee:
1304     newCallFrame->setThisValue(thisValue);
1305
1306     if (Profiler* profiler = globalData.enabledProfiler())
1307         profiler->willExecute(callFrame, eval->sourceURL(), eval->lineNo());
1308
1309     // Execute the code:
1310     JSValue result;
1311     {
1312         SamplingTool::CallRecord callRecord(m_sampler.get());
1313         
1314 #if ENABLE(LLINT_C_LOOP)
1315         result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
1316 #elif ENABLE(JIT)
1317         result = eval->generatedJITCode().execute(&m_stack, newCallFrame, &globalData);
1318 #endif // ENABLE(JIT)
1319     }
1320
1321     if (Profiler* profiler = globalData.enabledProfiler())
1322         profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
1323
1324     m_stack.popFrame(newCallFrame);
1325     return checkedReturn(result);
1326 }
1327
1328 NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine, int column)
1329 {
1330     Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
1331     if (!debugger)
1332         return;
1333
1334     switch (debugHookID) {
1335         case DidEnterCallFrame:
1336             debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
1337             return;
1338         case WillLeaveCallFrame:
1339             debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
1340             return;
1341         case WillExecuteStatement:
1342             debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
1343             return;
1344         case WillExecuteProgram:
1345             debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
1346             return;
1347         case DidExecuteProgram:
1348             debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
1349             return;
1350         case DidReachBreakpoint:
1351             debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
1352             return;
1353     }
1354 }
1355     
1356 JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
1357 {
1358     CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
1359     if (!functionCallFrame)
1360         return jsNull();
1361
1362     Arguments* arguments = Arguments::create(functionCallFrame->globalData(), functionCallFrame);
1363     arguments->tearOff(functionCallFrame);
1364     return JSValue(arguments);
1365 }
1366
1367 JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction* function) const
1368 {
1369     CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
1370
1371     if (!functionCallFrame)
1372         return jsNull();
1373     
1374     int lineNumber;
1375     unsigned bytecodeOffset;
1376     CallFrame* callerFrame = getCallerInfo(&callFrame->globalData(), functionCallFrame, lineNumber, bytecodeOffset);
1377     if (!callerFrame)
1378         return jsNull();
1379     JSValue caller = callerFrame->callee();
1380     if (!caller)
1381         return jsNull();
1382
1383     // Skip over function bindings.
1384     ASSERT(caller.isObject());
1385     while (asObject(caller)->inherits(&JSBoundFunction::s_info)) {
1386         callerFrame = getCallerInfo(&callFrame->globalData(), callerFrame, lineNumber, bytecodeOffset);
1387         if (!callerFrame)
1388             return jsNull();
1389         caller = callerFrame->callee();
1390         if (!caller)
1391             return jsNull();
1392     }
1393
1394     return caller;
1395 }
1396
1397 void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, String& sourceURL, JSValue& function) const
1398 {
1399     function = JSValue();
1400     lineNumber = -1;
1401     sourceURL = String();
1402
1403     CallFrame* callerFrame = callFrame->callerFrame();
1404     if (callerFrame->hasHostCallFrameFlag())
1405         return;
1406
1407     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
1408     if (!callerCodeBlock)
1409         return;
1410     unsigned bytecodeOffset = 0;
1411     bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
1412     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
1413     sourceID = callerCodeBlock->ownerExecutable()->sourceID();
1414     sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
1415     function = callerFrame->callee();
1416 }
1417
1418 CallFrame* Interpreter::findFunctionCallFrameFromVMCode(CallFrame* callFrame, JSFunction* function)
1419 {
1420     for (CallFrame* candidate = callFrame->trueCallFrameFromVMCode(); candidate; candidate = candidate->trueCallerFrame()) {
1421         if (candidate->callee() == function)
1422             return candidate;
1423     }
1424     return 0;
1425 }
1426
1427 void Interpreter::enableSampler()
1428 {
1429 #if ENABLE(OPCODE_SAMPLING)
1430     if (!m_sampler) {
1431         m_sampler = adoptPtr(new SamplingTool(this));
1432         m_sampler->setup();
1433     }
1434 #endif
1435 }
1436 void Interpreter::dumpSampleData(ExecState* exec)
1437 {
1438 #if ENABLE(OPCODE_SAMPLING)
1439     if (m_sampler)
1440         m_sampler->dump(exec);
1441 #else
1442     UNUSED_PARAM(exec);
1443 #endif
1444 }
1445 void Interpreter::startSampling()
1446 {
1447 #if ENABLE(SAMPLING_THREAD)
1448     if (!m_sampleEntryDepth)
1449         SamplingThread::start();
1450
1451     m_sampleEntryDepth++;
1452 #endif
1453 }
1454 void Interpreter::stopSampling()
1455 {
1456 #if ENABLE(SAMPLING_THREAD)
1457     m_sampleEntryDepth--;
1458     if (!m_sampleEntryDepth)
1459         SamplingThread::stop();
1460 #endif
1461 }
1462
1463 } // namespace JSC