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