1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "callee_save_frame.h"
18 #include "entrypoints/entrypoint_utils.h"
19 #include "mirror/object.h"
20 #include "object_utils.h"
21 #include "thread.h"
22 #include "well_known_classes.h"
23
24 namespace art {
25
26 // Deliver an exception that's pending on thread helping set up a callee save frame on the way.
artDeliverPendingExceptionFromCode(Thread * thread,mirror::ArtMethod ** sp)27 extern "C" void artDeliverPendingExceptionFromCode(Thread* thread, mirror::ArtMethod** sp)
28 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
29 FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
30 thread->QuickDeliverException();
31 }
32
33 // Called by generated call to throw an exception.
artDeliverExceptionFromCode(mirror::Throwable * exception,Thread * self,mirror::ArtMethod ** sp)34 extern "C" void artDeliverExceptionFromCode(mirror::Throwable* exception, Thread* self,
35 mirror::ArtMethod** sp)
36 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
37 /*
38 * exception may be NULL, in which case this routine should
39 * throw NPE. NOTE: this is a convenience for generated code,
40 * which previously did the null check inline and constructed
41 * and threw a NPE if NULL. This routine responsible for setting
42 * exception_ in thread and delivering the exception.
43 */
44 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
45 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
46 if (exception == NULL) {
47 self->ThrowNewException(throw_location, "Ljava/lang/NullPointerException;",
48 "throw with null exception");
49 } else {
50 self->SetException(throw_location, exception);
51 }
52 self->QuickDeliverException();
53 }
54
55 // Called by generated call to throw a NPE exception.
artThrowNullPointerExceptionFromCode(Thread * self,mirror::ArtMethod ** sp)56 extern "C" void artThrowNullPointerExceptionFromCode(Thread* self,
57 mirror::ArtMethod** sp)
58 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
59 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
60 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
61 ThrowNullPointerExceptionFromDexPC(throw_location);
62 self->QuickDeliverException();
63 }
64
65 // Called by generated call to throw an arithmetic divide by zero exception.
artThrowDivZeroFromCode(Thread * self,mirror::ArtMethod ** sp)66 extern "C" void artThrowDivZeroFromCode(Thread* self,
67 mirror::ArtMethod** sp)
68 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
69 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
70 ThrowArithmeticExceptionDivideByZero();
71 self->QuickDeliverException();
72 }
73
74 // Called by generated call to throw an array index out of bounds exception.
artThrowArrayBoundsFromCode(int index,int length,Thread * self,mirror::ArtMethod ** sp)75 extern "C" void artThrowArrayBoundsFromCode(int index, int length, Thread* self,
76 mirror::ArtMethod** sp)
77 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
78 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
79 ThrowArrayIndexOutOfBoundsException(index, length);
80 self->QuickDeliverException();
81 }
82
artThrowStackOverflowFromCode(Thread * self,mirror::ArtMethod ** sp)83 extern "C" void artThrowStackOverflowFromCode(Thread* self, mirror::ArtMethod** sp)
84 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
85 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
86 ThrowStackOverflowError(self);
87 self->QuickDeliverException();
88 }
89
artThrowNoSuchMethodFromCode(int32_t method_idx,Thread * self,mirror::ArtMethod ** sp)90 extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self,
91 mirror::ArtMethod** sp)
92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93 FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
94 ThrowNoSuchMethodError(method_idx);
95 self->QuickDeliverException();
96 }
97
98 } // namespace art
99