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