501d48b1ba09ab7b4d562a8ad3ae5fde83b3ab83
[WebKit-https.git] / Source / JavaScriptCore / jit / JITExceptions.cpp
1 /*
2  * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "JITExceptions.h"
28
29 #include "CallFrame.h"
30 #include "CodeBlock.h"
31 #include "Interpreter.h"
32 #include "JSCInlines.h"
33 #include "JSCJSValue.h"
34 #include "LLIntData.h"
35 #include "LLIntOpcode.h"
36 #include "LLIntThunks.h"
37 #include "Opcode.h"
38 #include "ShadowChicken.h"
39 #include "VM.h"
40
41 namespace JSC {
42
43 void genericUnwind(VM* vm, ExecState* callFrame, UnwindStart unwindStart)
44 {
45     auto scope = DECLARE_CATCH_SCOPE(*vm);
46     if (Options::breakOnThrow()) {
47         CodeBlock* codeBlock = callFrame->codeBlock();
48         if (codeBlock)
49             dataLog("In call frame ", RawPointer(callFrame), " for code block ", *codeBlock, "\n");
50         else
51             dataLog("In call frame ", RawPointer(callFrame), " with null CodeBlock\n");
52         CRASH();
53     }
54     
55     ExecState* shadowChickenTopFrame = callFrame;
56     if (unwindStart == UnwindFromCallerFrame) {
57         VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame;
58         shadowChickenTopFrame = callFrame->callerFrame(topVMEntryFrame);
59     }
60     vm->shadowChicken().log(*vm, shadowChickenTopFrame, ShadowChicken::Packet::throwPacket());
61     
62     Exception* exception = scope.exception();
63     RELEASE_ASSERT(exception);
64     HandlerInfo* handler = vm->interpreter->unwind(*vm, callFrame, exception, unwindStart); // This may update callFrame.
65
66     void* catchRoutine;
67     Instruction* catchPCForInterpreter = 0;
68     if (handler) {
69         // handler->target is meaningless for getting a code offset when catching
70         // the exception in a DFG/FTL frame. This bytecode target offset could be
71         // something that's in an inlined frame, which means an array access
72         // with this bytecode offset in the machine frame is utterly meaningless
73         // and can cause an overflow. OSR exit properly exits to handler->target
74         // in the proper frame.
75         if (!JITCode::isOptimizingJIT(callFrame->codeBlock()->jitType()))
76             catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
77 #if ENABLE(JIT)
78         catchRoutine = handler->nativeCode.executableAddress();
79 #else
80         catchRoutine = catchPCForInterpreter->u.pointer;
81 #endif
82     } else
83         catchRoutine = LLInt::getCodePtr(handleUncaughtException);
84     
85     ASSERT(bitwise_cast<uintptr_t>(callFrame) < bitwise_cast<uintptr_t>(vm->topVMEntryFrame));
86
87     vm->callFrameForCatch = callFrame;
88     vm->targetMachinePCForThrow = catchRoutine;
89     vm->targetInterpreterPCForThrow = catchPCForInterpreter;
90     
91     RELEASE_ASSERT(catchRoutine);
92 }
93
94 void genericUnwind(VM* vm, ExecState* callFrame)
95 {
96     genericUnwind(vm, callFrame, UnwindFromCurrentFrame);
97 }
98
99 } // namespace JSC