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