Merge remote-tracking branch 'redux/master' into sh4-pool
[tamarin-stm.git] / core / Exception.cpp
blobd1ee87958fd8a6a52b2633c501d64d1de9b168da
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2006
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adobe AS3 Team
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 #include "avmplus.h"
43 #if defined(AVMPLUS_AMD64) && defined(_WIN64)
44 extern "C"
46 _int64 __cdecl longjmp64(jmp_buf jmpbuf, _int64 arg);
48 #endif
50 #if (defined(AVMPLUS_MAC) || defined(linux)) && defined(DEBUG)
51 // definition in PosixPortUtils.cpp
52 void assertSignalMask(uint32_t expected);
53 uint32_t querySignalMask();
54 #endif
57 namespace avmplus
60 // Exception
63 Exception::Exception(AvmCore* core, Atom atom)
65 this->atom = atom;
66 this->flags = 0;
68 #ifdef DEBUGGER
69 // If the exception atom is an Error object, copy its stack trace.
70 // Otherwise, generate a new stack trace.
71 if (AvmCore::istype(atom, core->traits.error_itraits))
73 stackTrace = ((ErrorObject*)AvmCore::atomToScriptObject(atom))->getStackTraceObject();
75 else
77 stackTrace = core->newStackTrace();
79 #else
80 (void)core;
81 #endif
84 bool Exception::isValid()
86 return atomKind(atom) == kObjectType;
90 // ExceptionHandlerTable
93 ExceptionHandlerTable::ExceptionHandlerTable(int exception_count)
94 : exception_count(exception_count)
99 // ExceptionFrame
102 void ExceptionFrame::beginTry(AvmCore* core)
104 this->core = core;
106 prevFrame = core->exceptionFrame;
108 if (!prevFrame) {
109 // Do special setup for first frame
110 core->setStackBase();
113 core->exceptionFrame = this;
115 #ifdef DEBUGGER
116 callStack = core->callStack;
117 #endif /* DEBUGGER */
119 // beginTry() is called from both the TRY macro and from JIT'd code. The TRY
120 // macro will immediately change the value of catchAction right after the
121 // call to beginTry(); but the JIT'd code does not change catchAction. So,
122 // we initialize catchAction to the value that it needs when we're called
123 // from JIT'd code, that is, kCatchAction_SearchForActionScriptExceptionHandler.
124 catchAction = kCatchAction_SearchForActionScriptExceptionHandler;
126 this->stacktop = core->gc->allocaTop();
128 savedMethodFrame = core->currentMethodFrame;
129 #ifdef VMCFG_AOT
130 this->llvmUnwindStyle = 0;
131 #endif
133 #if (defined(AVMPLUS_MAC) || defined(linux)) && defined(DEBUG)
134 this->contextExtra = querySignalMask();
135 #endif
138 #ifdef VMCFG_AOT
139 void ExceptionFrame::beginLlvmUnwindTry(AvmCore *core)
141 beginTry(core);
142 this->llvmUnwindStyle = 1;
144 #endif
148 void ExceptionFrame::endTry()
150 if (core) {
151 // ISSUE do we need to check core if it is set in constructor?
152 core->exceptionFrame = prevFrame;
154 core->gc->allocaPopTo(this->stacktop);
156 core->currentMethodFrame = savedMethodFrame;
160 void ExceptionFrame::throwException(Exception *exception)
162 core->exceptionAddr = exception;
163 #ifdef VMCFG_AOT
164 if(this->llvmUnwindStyle) {
165 llvm_unwind();
166 return;
168 #endif
170 VMPI_longjmpNoUnwind(jmpbuf, 1);
173 void ExceptionFrame::beginCatch()
175 core->exceptionFrame = prevFrame;
177 #if (defined(AVMPLUS_MAC) || defined(linux)) && defined(DEBUG)
178 assertSignalMask(this->contextExtra);
179 #endif
182 #ifdef DEBUGGER
183 core->callStack = callStack;
184 #endif // DEBUGGER
186 core->currentMethodFrame = savedMethodFrame;
188 core->gc->allocaPopTo(this->stacktop);