1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "common_throws.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <sstream>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
22*795d594fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
25*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
26*795d594fSAndroid Build Coastguard Worker #include "art_method.h"
27*795d594fSAndroid Build Coastguard Worker #include "class_linker-inl.h"
28*795d594fSAndroid Build Coastguard Worker #include "debug_print.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
30*795d594fSAndroid Build Coastguard Worker #include "dex/dex_instruction-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "dex/invoke_type.h"
32*795d594fSAndroid Build Coastguard Worker #include "mirror/class-alloc-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "mirror/method_type.h"
34*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_local_ref.h"
37*795d594fSAndroid Build Coastguard Worker #include "obj_ptr-inl.h"
38*795d594fSAndroid Build Coastguard Worker #include "thread.h"
39*795d594fSAndroid Build Coastguard Worker #include "well_known_classes-inl.h"
40*795d594fSAndroid Build Coastguard Worker
41*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
42*795d594fSAndroid Build Coastguard Worker
43*795d594fSAndroid Build Coastguard Worker using android::base::StringAppendV;
44*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
45*795d594fSAndroid Build Coastguard Worker
AddReferrerLocation(std::ostream & os,ObjPtr<mirror::Class> referrer)46*795d594fSAndroid Build Coastguard Worker static void AddReferrerLocation(std::ostream& os, ObjPtr<mirror::Class> referrer)
47*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
48*795d594fSAndroid Build Coastguard Worker if (referrer != nullptr) {
49*795d594fSAndroid Build Coastguard Worker std::string location(referrer->GetLocation());
50*795d594fSAndroid Build Coastguard Worker if (!location.empty()) {
51*795d594fSAndroid Build Coastguard Worker os << " (declaration of '" << referrer->PrettyDescriptor()
52*795d594fSAndroid Build Coastguard Worker << "' appears in " << location << ")";
53*795d594fSAndroid Build Coastguard Worker }
54*795d594fSAndroid Build Coastguard Worker }
55*795d594fSAndroid Build Coastguard Worker }
56*795d594fSAndroid Build Coastguard Worker
ThrowException(const char * exception_descriptor)57*795d594fSAndroid Build Coastguard Worker static void ThrowException(const char* exception_descriptor) REQUIRES_SHARED(Locks::mutator_lock_) {
58*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
59*795d594fSAndroid Build Coastguard Worker self->ThrowNewException(exception_descriptor, nullptr);
60*795d594fSAndroid Build Coastguard Worker }
61*795d594fSAndroid Build Coastguard Worker
ThrowException(const char * exception_descriptor,ObjPtr<mirror::Class> referrer,const char * fmt,va_list * args=nullptr)62*795d594fSAndroid Build Coastguard Worker static void ThrowException(const char* exception_descriptor,
63*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> referrer,
64*795d594fSAndroid Build Coastguard Worker const char* fmt,
65*795d594fSAndroid Build Coastguard Worker va_list* args = nullptr)
66*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
67*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
68*795d594fSAndroid Build Coastguard Worker if (args != nullptr) {
69*795d594fSAndroid Build Coastguard Worker std::string vmsg;
70*795d594fSAndroid Build Coastguard Worker StringAppendV(&vmsg, fmt, *args);
71*795d594fSAndroid Build Coastguard Worker msg << vmsg;
72*795d594fSAndroid Build Coastguard Worker } else {
73*795d594fSAndroid Build Coastguard Worker msg << fmt;
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker AddReferrerLocation(msg, referrer);
76*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
77*795d594fSAndroid Build Coastguard Worker self->ThrowNewException(exception_descriptor, msg.str().c_str());
78*795d594fSAndroid Build Coastguard Worker }
79*795d594fSAndroid Build Coastguard Worker
ThrowWrappedException(const char * exception_descriptor,ObjPtr<mirror::Class> referrer,const char * fmt,va_list * args=nullptr)80*795d594fSAndroid Build Coastguard Worker static void ThrowWrappedException(const char* exception_descriptor,
81*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> referrer,
82*795d594fSAndroid Build Coastguard Worker const char* fmt,
83*795d594fSAndroid Build Coastguard Worker va_list* args = nullptr)
84*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
85*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
86*795d594fSAndroid Build Coastguard Worker if (args != nullptr) {
87*795d594fSAndroid Build Coastguard Worker std::string vmsg;
88*795d594fSAndroid Build Coastguard Worker StringAppendV(&vmsg, fmt, *args);
89*795d594fSAndroid Build Coastguard Worker msg << vmsg;
90*795d594fSAndroid Build Coastguard Worker } else {
91*795d594fSAndroid Build Coastguard Worker msg << fmt;
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker AddReferrerLocation(msg, referrer);
94*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
95*795d594fSAndroid Build Coastguard Worker self->ThrowNewWrappedException(exception_descriptor, msg.str().c_str());
96*795d594fSAndroid Build Coastguard Worker }
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker // AbstractMethodError
99*795d594fSAndroid Build Coastguard Worker
ThrowAbstractMethodError(ArtMethod * method)100*795d594fSAndroid Build Coastguard Worker void ThrowAbstractMethodError(ArtMethod* method) {
101*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/AbstractMethodError;", nullptr,
102*795d594fSAndroid Build Coastguard Worker StringPrintf("abstract method \"%s\"",
103*795d594fSAndroid Build Coastguard Worker ArtMethod::PrettyMethod(method).c_str()).c_str());
104*795d594fSAndroid Build Coastguard Worker }
105*795d594fSAndroid Build Coastguard Worker
ThrowAbstractMethodError(uint32_t method_idx,const DexFile & dex_file)106*795d594fSAndroid Build Coastguard Worker void ThrowAbstractMethodError(uint32_t method_idx, const DexFile& dex_file) {
107*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/AbstractMethodError;", /* referrer= */ nullptr,
108*795d594fSAndroid Build Coastguard Worker StringPrintf("abstract method \"%s\"",
109*795d594fSAndroid Build Coastguard Worker dex_file.PrettyMethod(method_idx,
110*795d594fSAndroid Build Coastguard Worker /* with_signature= */ true).c_str()).c_str());
111*795d594fSAndroid Build Coastguard Worker }
112*795d594fSAndroid Build Coastguard Worker
113*795d594fSAndroid Build Coastguard Worker // ArithmeticException
114*795d594fSAndroid Build Coastguard Worker
ThrowArithmeticExceptionDivideByZero()115*795d594fSAndroid Build Coastguard Worker void ThrowArithmeticExceptionDivideByZero() {
116*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ArithmeticException;", nullptr, "divide by zero");
117*795d594fSAndroid Build Coastguard Worker }
118*795d594fSAndroid Build Coastguard Worker
119*795d594fSAndroid Build Coastguard Worker // ArrayIndexOutOfBoundsException
120*795d594fSAndroid Build Coastguard Worker
ThrowArrayIndexOutOfBoundsException(int index,int length)121*795d594fSAndroid Build Coastguard Worker void ThrowArrayIndexOutOfBoundsException(int index, int length) {
122*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", nullptr,
123*795d594fSAndroid Build Coastguard Worker StringPrintf("length=%d; index=%d", length, index).c_str());
124*795d594fSAndroid Build Coastguard Worker }
125*795d594fSAndroid Build Coastguard Worker
126*795d594fSAndroid Build Coastguard Worker // ArrayStoreException
127*795d594fSAndroid Build Coastguard Worker
ThrowArrayStoreException(ObjPtr<mirror::Class> element_class,ObjPtr<mirror::Class> array_class)128*795d594fSAndroid Build Coastguard Worker void ThrowArrayStoreException(ObjPtr<mirror::Class> element_class,
129*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> array_class) {
130*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ArrayStoreException;", nullptr,
131*795d594fSAndroid Build Coastguard Worker StringPrintf("%s cannot be stored in an array of type %s",
132*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(element_class).c_str(),
133*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(array_class).c_str()).c_str());
134*795d594fSAndroid Build Coastguard Worker }
135*795d594fSAndroid Build Coastguard Worker
136*795d594fSAndroid Build Coastguard Worker // BootstrapMethodError
137*795d594fSAndroid Build Coastguard Worker
ThrowBootstrapMethodError(const char * fmt,...)138*795d594fSAndroid Build Coastguard Worker void ThrowBootstrapMethodError(const char* fmt, ...) {
139*795d594fSAndroid Build Coastguard Worker va_list args;
140*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
141*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/BootstrapMethodError;", nullptr, fmt, &args);
142*795d594fSAndroid Build Coastguard Worker va_end(args);
143*795d594fSAndroid Build Coastguard Worker }
144*795d594fSAndroid Build Coastguard Worker
ThrowWrappedBootstrapMethodError(const char * fmt,...)145*795d594fSAndroid Build Coastguard Worker void ThrowWrappedBootstrapMethodError(const char* fmt, ...) {
146*795d594fSAndroid Build Coastguard Worker va_list args;
147*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
148*795d594fSAndroid Build Coastguard Worker ThrowWrappedException("Ljava/lang/BootstrapMethodError;", nullptr, fmt, &args);
149*795d594fSAndroid Build Coastguard Worker va_end(args);
150*795d594fSAndroid Build Coastguard Worker }
151*795d594fSAndroid Build Coastguard Worker
152*795d594fSAndroid Build Coastguard Worker // ClassCastException
153*795d594fSAndroid Build Coastguard Worker
ThrowClassCastException(ObjPtr<mirror::Class> dest_type,ObjPtr<mirror::Class> src_type)154*795d594fSAndroid Build Coastguard Worker void ThrowClassCastException(ObjPtr<mirror::Class> dest_type, ObjPtr<mirror::Class> src_type) {
155*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ClassCastException;", nullptr,
156*795d594fSAndroid Build Coastguard Worker StringPrintf("%s cannot be cast to %s",
157*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(src_type).c_str(),
158*795d594fSAndroid Build Coastguard Worker mirror::Class::PrettyDescriptor(dest_type).c_str()).c_str());
159*795d594fSAndroid Build Coastguard Worker }
160*795d594fSAndroid Build Coastguard Worker
ThrowClassCastException(const char * msg)161*795d594fSAndroid Build Coastguard Worker void ThrowClassCastException(const char* msg) {
162*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ClassCastException;", nullptr, msg);
163*795d594fSAndroid Build Coastguard Worker }
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker // ClassCircularityError
166*795d594fSAndroid Build Coastguard Worker
ThrowClassCircularityError(ObjPtr<mirror::Class> c)167*795d594fSAndroid Build Coastguard Worker void ThrowClassCircularityError(ObjPtr<mirror::Class> c) {
168*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
169*795d594fSAndroid Build Coastguard Worker msg << mirror::Class::PrettyDescriptor(c);
170*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
171*795d594fSAndroid Build Coastguard Worker }
172*795d594fSAndroid Build Coastguard Worker
ThrowClassCircularityError(ObjPtr<mirror::Class> c,const char * fmt,...)173*795d594fSAndroid Build Coastguard Worker void ThrowClassCircularityError(ObjPtr<mirror::Class> c, const char* fmt, ...) {
174*795d594fSAndroid Build Coastguard Worker va_list args;
175*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
176*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ClassCircularityError;", c, fmt, &args);
177*795d594fSAndroid Build Coastguard Worker va_end(args);
178*795d594fSAndroid Build Coastguard Worker }
179*795d594fSAndroid Build Coastguard Worker
180*795d594fSAndroid Build Coastguard Worker // ClassFormatError
181*795d594fSAndroid Build Coastguard Worker
ThrowClassFormatError(ObjPtr<mirror::Class> referrer,const char * fmt,...)182*795d594fSAndroid Build Coastguard Worker void ThrowClassFormatError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
183*795d594fSAndroid Build Coastguard Worker va_list args;
184*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
185*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/ClassFormatError;", referrer, fmt, &args);
186*795d594fSAndroid Build Coastguard Worker va_end(args);
187*795d594fSAndroid Build Coastguard Worker }
188*795d594fSAndroid Build Coastguard Worker
189*795d594fSAndroid Build Coastguard Worker // IllegalAccessError
190*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessErrorClass(ObjPtr<mirror::Class> referrer,ObjPtr<mirror::Class> accessed)191*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessErrorClass(ObjPtr<mirror::Class> referrer, ObjPtr<mirror::Class> accessed) {
192*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
193*795d594fSAndroid Build Coastguard Worker msg << "Illegal class access: '" << mirror::Class::PrettyDescriptor(referrer)
194*795d594fSAndroid Build Coastguard Worker << "' attempting to access '" << mirror::Class::PrettyDescriptor(accessed) << "'";
195*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
196*795d594fSAndroid Build Coastguard Worker }
197*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessErrorClassForMethodDispatch(ObjPtr<mirror::Class> referrer,ObjPtr<mirror::Class> accessed,ArtMethod * called,InvokeType type)198*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessErrorClassForMethodDispatch(ObjPtr<mirror::Class> referrer,
199*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> accessed,
200*795d594fSAndroid Build Coastguard Worker ArtMethod* called,
201*795d594fSAndroid Build Coastguard Worker InvokeType type) {
202*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
203*795d594fSAndroid Build Coastguard Worker msg << "Illegal class access ('" << mirror::Class::PrettyDescriptor(referrer)
204*795d594fSAndroid Build Coastguard Worker << "' attempting to access '"
205*795d594fSAndroid Build Coastguard Worker << mirror::Class::PrettyDescriptor(accessed) << "') in attempt to invoke " << type
206*795d594fSAndroid Build Coastguard Worker << " method " << ArtMethod::PrettyMethod(called).c_str();
207*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
208*795d594fSAndroid Build Coastguard Worker }
209*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessErrorMethod(ObjPtr<mirror::Class> referrer,ArtMethod * accessed)210*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessErrorMethod(ObjPtr<mirror::Class> referrer, ArtMethod* accessed) {
211*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
212*795d594fSAndroid Build Coastguard Worker msg << "Method '" << ArtMethod::PrettyMethod(accessed) << "' is inaccessible to class '"
213*795d594fSAndroid Build Coastguard Worker << mirror::Class::PrettyDescriptor(referrer) << "'";
214*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
215*795d594fSAndroid Build Coastguard Worker }
216*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessErrorField(ObjPtr<mirror::Class> referrer,ArtField * accessed)217*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessErrorField(ObjPtr<mirror::Class> referrer, ArtField* accessed) {
218*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
219*795d594fSAndroid Build Coastguard Worker msg << "Field '" << ArtField::PrettyField(accessed, false) << "' is inaccessible to class '"
220*795d594fSAndroid Build Coastguard Worker << mirror::Class::PrettyDescriptor(referrer) << "'";
221*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
222*795d594fSAndroid Build Coastguard Worker }
223*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessErrorFinalField(ArtMethod * referrer,ArtField * accessed)224*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessErrorFinalField(ArtMethod* referrer, ArtField* accessed) {
225*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
226*795d594fSAndroid Build Coastguard Worker msg << "Final field '" << ArtField::PrettyField(accessed, false)
227*795d594fSAndroid Build Coastguard Worker << "' cannot be written to by method '" << ArtMethod::PrettyMethod(referrer) << "'";
228*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessError;",
229*795d594fSAndroid Build Coastguard Worker referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
230*795d594fSAndroid Build Coastguard Worker msg.str().c_str());
231*795d594fSAndroid Build Coastguard Worker }
232*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessError(ObjPtr<mirror::Class> referrer,const char * fmt,...)233*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
234*795d594fSAndroid Build Coastguard Worker va_list args;
235*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
236*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
237*795d594fSAndroid Build Coastguard Worker va_end(args);
238*795d594fSAndroid Build Coastguard Worker }
239*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessErrorForImplementingMethod(ObjPtr<mirror::Class> klass,ArtMethod * implementation_method,ArtMethod * interface_method)240*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessErrorForImplementingMethod(ObjPtr<mirror::Class> klass,
241*795d594fSAndroid Build Coastguard Worker ArtMethod* implementation_method,
242*795d594fSAndroid Build Coastguard Worker ArtMethod* interface_method)
243*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
244*795d594fSAndroid Build Coastguard Worker // Note: For a non-public abstract implementing method, both `AbstractMethodError` and
245*795d594fSAndroid Build Coastguard Worker // `IllegalAccessError` are reasonable. We now follow the RI behaviour and throw the latter,
246*795d594fSAndroid Build Coastguard Worker // so we do not assert here that the implementation method is concrete as we did in the past.
247*795d594fSAndroid Build Coastguard Worker DCHECK(!implementation_method->IsPublic());
248*795d594fSAndroid Build Coastguard Worker ThrowIllegalAccessError(
249*795d594fSAndroid Build Coastguard Worker klass,
250*795d594fSAndroid Build Coastguard Worker "Method '%s' implementing interface method '%s' is not public",
251*795d594fSAndroid Build Coastguard Worker implementation_method->PrettyMethod().c_str(),
252*795d594fSAndroid Build Coastguard Worker interface_method->PrettyMethod().c_str());
253*795d594fSAndroid Build Coastguard Worker }
254*795d594fSAndroid Build Coastguard Worker
255*795d594fSAndroid Build Coastguard Worker // IllegalAccessException
256*795d594fSAndroid Build Coastguard Worker
ThrowIllegalAccessException(const char * msg)257*795d594fSAndroid Build Coastguard Worker void ThrowIllegalAccessException(const char* msg) {
258*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalAccessException;", nullptr, msg);
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker
261*795d594fSAndroid Build Coastguard Worker // IllegalArgumentException
262*795d594fSAndroid Build Coastguard Worker
ThrowIllegalArgumentException(const char * msg)263*795d594fSAndroid Build Coastguard Worker void ThrowIllegalArgumentException(const char* msg) {
264*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalArgumentException;", nullptr, msg);
265*795d594fSAndroid Build Coastguard Worker }
266*795d594fSAndroid Build Coastguard Worker
267*795d594fSAndroid Build Coastguard Worker // IllegalStateException
268*795d594fSAndroid Build Coastguard Worker
ThrowIllegalStateException(const char * msg)269*795d594fSAndroid Build Coastguard Worker void ThrowIllegalStateException(const char* msg) {
270*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IllegalStateException;", nullptr, msg);
271*795d594fSAndroid Build Coastguard Worker }
272*795d594fSAndroid Build Coastguard Worker
273*795d594fSAndroid Build Coastguard Worker // IncompatibleClassChangeError
274*795d594fSAndroid Build Coastguard Worker
ThrowIncompatibleClassChangeError(InvokeType expected_type,InvokeType found_type,ArtMethod * method,ArtMethod * referrer)275*795d594fSAndroid Build Coastguard Worker void ThrowIncompatibleClassChangeError(InvokeType expected_type,
276*795d594fSAndroid Build Coastguard Worker InvokeType found_type,
277*795d594fSAndroid Build Coastguard Worker ArtMethod* method,
278*795d594fSAndroid Build Coastguard Worker ArtMethod* referrer) {
279*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
280*795d594fSAndroid Build Coastguard Worker msg << "The method '" << ArtMethod::PrettyMethod(method) << "' was expected to be of type "
281*795d594fSAndroid Build Coastguard Worker << expected_type << " but instead was found to be of type " << found_type;
282*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IncompatibleClassChangeError;",
283*795d594fSAndroid Build Coastguard Worker referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
284*795d594fSAndroid Build Coastguard Worker msg.str().c_str());
285*795d594fSAndroid Build Coastguard Worker }
286*795d594fSAndroid Build Coastguard Worker
ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod * interface_method,ObjPtr<mirror::Object> this_object,ArtMethod * referrer)287*795d594fSAndroid Build Coastguard Worker void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* interface_method,
288*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object,
289*795d594fSAndroid Build Coastguard Worker ArtMethod* referrer) {
290*795d594fSAndroid Build Coastguard Worker // Referrer is calling interface_method on this_object, however, the interface_method isn't
291*795d594fSAndroid Build Coastguard Worker // implemented by this_object.
292*795d594fSAndroid Build Coastguard Worker CHECK(this_object != nullptr);
293*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
294*795d594fSAndroid Build Coastguard Worker msg << "Class '" << mirror::Class::PrettyDescriptor(this_object->GetClass())
295*795d594fSAndroid Build Coastguard Worker << "' does not implement interface '"
296*795d594fSAndroid Build Coastguard Worker << mirror::Class::PrettyDescriptor(interface_method->GetDeclaringClass())
297*795d594fSAndroid Build Coastguard Worker << "' in call to '" << ArtMethod::PrettyMethod(interface_method) << "'";
298*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IncompatibleClassChangeError;",
299*795d594fSAndroid Build Coastguard Worker referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
300*795d594fSAndroid Build Coastguard Worker msg.str().c_str());
301*795d594fSAndroid Build Coastguard Worker }
302*795d594fSAndroid Build Coastguard Worker
ThrowIncompatibleClassChangeErrorField(ArtField * resolved_field,bool is_static,ArtMethod * referrer)303*795d594fSAndroid Build Coastguard Worker void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field,
304*795d594fSAndroid Build Coastguard Worker bool is_static,
305*795d594fSAndroid Build Coastguard Worker ArtMethod* referrer) {
306*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
307*795d594fSAndroid Build Coastguard Worker msg << "Expected '" << ArtField::PrettyField(resolved_field) << "' to be a "
308*795d594fSAndroid Build Coastguard Worker << (is_static ? "static" : "instance") << " field" << " rather than a "
309*795d594fSAndroid Build Coastguard Worker << (is_static ? "instance" : "static") << " field";
310*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer->GetDeclaringClass(),
311*795d594fSAndroid Build Coastguard Worker msg.str().c_str());
312*795d594fSAndroid Build Coastguard Worker }
313*795d594fSAndroid Build Coastguard Worker
ThrowIncompatibleClassChangeError(ObjPtr<mirror::Class> referrer,const char * fmt,...)314*795d594fSAndroid Build Coastguard Worker void ThrowIncompatibleClassChangeError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
315*795d594fSAndroid Build Coastguard Worker va_list args;
316*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
317*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
318*795d594fSAndroid Build Coastguard Worker va_end(args);
319*795d594fSAndroid Build Coastguard Worker }
320*795d594fSAndroid Build Coastguard Worker
ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod * method)321*795d594fSAndroid Build Coastguard Worker void ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod* method) {
322*795d594fSAndroid Build Coastguard Worker DCHECK(method != nullptr);
323*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IncompatibleClassChangeError;",
324*795d594fSAndroid Build Coastguard Worker /*referrer=*/nullptr,
325*795d594fSAndroid Build Coastguard Worker StringPrintf("Conflicting default method implementations %s",
326*795d594fSAndroid Build Coastguard Worker ArtMethod::PrettyMethod(method).c_str()).c_str());
327*795d594fSAndroid Build Coastguard Worker }
328*795d594fSAndroid Build Coastguard Worker
329*795d594fSAndroid Build Coastguard Worker // IndexOutOfBoundsException
330*795d594fSAndroid Build Coastguard Worker
ThrowIndexOutOfBoundsException(int index,int length)331*795d594fSAndroid Build Coastguard Worker void ThrowIndexOutOfBoundsException(int index, int length) {
332*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/IndexOutOfBoundsException;", nullptr,
333*795d594fSAndroid Build Coastguard Worker StringPrintf("length=%d; index=%d", length, index).c_str());
334*795d594fSAndroid Build Coastguard Worker }
335*795d594fSAndroid Build Coastguard Worker
336*795d594fSAndroid Build Coastguard Worker // InternalError
337*795d594fSAndroid Build Coastguard Worker
ThrowInternalError(const char * fmt,...)338*795d594fSAndroid Build Coastguard Worker void ThrowInternalError(const char* fmt, ...) {
339*795d594fSAndroid Build Coastguard Worker va_list args;
340*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
341*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/InternalError;", nullptr, fmt, &args);
342*795d594fSAndroid Build Coastguard Worker va_end(args);
343*795d594fSAndroid Build Coastguard Worker }
344*795d594fSAndroid Build Coastguard Worker
345*795d594fSAndroid Build Coastguard Worker // IOException
346*795d594fSAndroid Build Coastguard Worker
ThrowIOException(const char * fmt,...)347*795d594fSAndroid Build Coastguard Worker void ThrowIOException(const char* fmt, ...) {
348*795d594fSAndroid Build Coastguard Worker va_list args;
349*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
350*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/io/IOException;", nullptr, fmt, &args);
351*795d594fSAndroid Build Coastguard Worker va_end(args);
352*795d594fSAndroid Build Coastguard Worker }
353*795d594fSAndroid Build Coastguard Worker
ThrowWrappedIOException(const char * fmt,...)354*795d594fSAndroid Build Coastguard Worker void ThrowWrappedIOException(const char* fmt, ...) {
355*795d594fSAndroid Build Coastguard Worker va_list args;
356*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
357*795d594fSAndroid Build Coastguard Worker ThrowWrappedException("Ljava/io/IOException;", nullptr, fmt, &args);
358*795d594fSAndroid Build Coastguard Worker va_end(args);
359*795d594fSAndroid Build Coastguard Worker }
360*795d594fSAndroid Build Coastguard Worker
361*795d594fSAndroid Build Coastguard Worker // LinkageError
362*795d594fSAndroid Build Coastguard Worker
ThrowLinkageError(ObjPtr<mirror::Class> referrer,const char * fmt,...)363*795d594fSAndroid Build Coastguard Worker void ThrowLinkageError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
364*795d594fSAndroid Build Coastguard Worker va_list args;
365*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
366*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/LinkageError;", referrer, fmt, &args);
367*795d594fSAndroid Build Coastguard Worker va_end(args);
368*795d594fSAndroid Build Coastguard Worker }
369*795d594fSAndroid Build Coastguard Worker
ThrowWrappedLinkageError(ObjPtr<mirror::Class> referrer,const char * fmt,...)370*795d594fSAndroid Build Coastguard Worker void ThrowWrappedLinkageError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
371*795d594fSAndroid Build Coastguard Worker va_list args;
372*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
373*795d594fSAndroid Build Coastguard Worker ThrowWrappedException("Ljava/lang/LinkageError;", referrer, fmt, &args);
374*795d594fSAndroid Build Coastguard Worker va_end(args);
375*795d594fSAndroid Build Coastguard Worker }
376*795d594fSAndroid Build Coastguard Worker
377*795d594fSAndroid Build Coastguard Worker // NegativeArraySizeException
378*795d594fSAndroid Build Coastguard Worker
ThrowNegativeArraySizeException(int size)379*795d594fSAndroid Build Coastguard Worker void ThrowNegativeArraySizeException(int size) {
380*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr,
381*795d594fSAndroid Build Coastguard Worker StringPrintf("%d", size).c_str());
382*795d594fSAndroid Build Coastguard Worker }
383*795d594fSAndroid Build Coastguard Worker
ThrowNegativeArraySizeException(const char * msg)384*795d594fSAndroid Build Coastguard Worker void ThrowNegativeArraySizeException(const char* msg) {
385*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, msg);
386*795d594fSAndroid Build Coastguard Worker }
387*795d594fSAndroid Build Coastguard Worker
388*795d594fSAndroid Build Coastguard Worker // NoSuchFieldError
389*795d594fSAndroid Build Coastguard Worker
ThrowNoSuchFieldError(std::string_view scope,ObjPtr<mirror::Class> c,std::string_view type,std::string_view name)390*795d594fSAndroid Build Coastguard Worker void ThrowNoSuchFieldError(std::string_view scope,
391*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> c,
392*795d594fSAndroid Build Coastguard Worker std::string_view type,
393*795d594fSAndroid Build Coastguard Worker std::string_view name) {
394*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
395*795d594fSAndroid Build Coastguard Worker std::string temp;
396*795d594fSAndroid Build Coastguard Worker msg << "No " << scope << "field " << name << " of type " << type
397*795d594fSAndroid Build Coastguard Worker << " in class " << c->GetDescriptor(&temp) << " or its superclasses";
398*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
399*795d594fSAndroid Build Coastguard Worker }
400*795d594fSAndroid Build Coastguard Worker
ThrowNoSuchFieldException(ObjPtr<mirror::Class> c,std::string_view name)401*795d594fSAndroid Build Coastguard Worker void ThrowNoSuchFieldException(ObjPtr<mirror::Class> c, std::string_view name) {
402*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
403*795d594fSAndroid Build Coastguard Worker std::string temp;
404*795d594fSAndroid Build Coastguard Worker msg << "No field " << name << " in class " << c->GetDescriptor(&temp);
405*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NoSuchFieldException;", c, msg.str().c_str());
406*795d594fSAndroid Build Coastguard Worker }
407*795d594fSAndroid Build Coastguard Worker
408*795d594fSAndroid Build Coastguard Worker // NoSuchMethodError
409*795d594fSAndroid Build Coastguard Worker
ThrowNoSuchMethodError(InvokeType type,ObjPtr<mirror::Class> c,std::string_view name,const Signature & signature)410*795d594fSAndroid Build Coastguard Worker void ThrowNoSuchMethodError(InvokeType type,
411*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> c,
412*795d594fSAndroid Build Coastguard Worker std::string_view name,
413*795d594fSAndroid Build Coastguard Worker const Signature& signature) {
414*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
415*795d594fSAndroid Build Coastguard Worker std::string temp;
416*795d594fSAndroid Build Coastguard Worker msg << "No " << type << " method " << name << signature
417*795d594fSAndroid Build Coastguard Worker << " in class " << c->GetDescriptor(&temp) << " or its super classes";
418*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
419*795d594fSAndroid Build Coastguard Worker }
420*795d594fSAndroid Build Coastguard Worker
ThrowNoSuchMethodError(ObjPtr<mirror::Class> c,std::string_view name,const Signature & signature)421*795d594fSAndroid Build Coastguard Worker void ThrowNoSuchMethodError(ObjPtr<mirror::Class> c,
422*795d594fSAndroid Build Coastguard Worker std::string_view name,
423*795d594fSAndroid Build Coastguard Worker const Signature& signature) {
424*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
425*795d594fSAndroid Build Coastguard Worker std::string temp;
426*795d594fSAndroid Build Coastguard Worker msg << "No method " << name << signature
427*795d594fSAndroid Build Coastguard Worker << " in class " << c->GetDescriptor(&temp) << " or its super classes";
428*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
429*795d594fSAndroid Build Coastguard Worker }
430*795d594fSAndroid Build Coastguard Worker
431*795d594fSAndroid Build Coastguard Worker // NullPointerException
432*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerExceptionForFieldAccess(ArtField * field,ArtMethod * method,bool is_read)433*795d594fSAndroid Build Coastguard Worker void ThrowNullPointerExceptionForFieldAccess(ArtField* field, ArtMethod* method, bool is_read) {
434*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
435*795d594fSAndroid Build Coastguard Worker msg << "Attempt to " << (is_read ? "read from" : "write to") << " field '"
436*795d594fSAndroid Build Coastguard Worker << ArtField::PrettyField(field) << "' on a null object reference in method '"
437*795d594fSAndroid Build Coastguard Worker << ArtMethod::PrettyMethod(method) << "'";
438*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
439*795d594fSAndroid Build Coastguard Worker }
440*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx,const DexFile & dex_file,InvokeType type)441*795d594fSAndroid Build Coastguard Worker static void ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx,
442*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file,
443*795d594fSAndroid Build Coastguard Worker InvokeType type)
444*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
445*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
446*795d594fSAndroid Build Coastguard Worker msg << "Attempt to invoke " << type << " method '"
447*795d594fSAndroid Build Coastguard Worker << dex_file.PrettyMethod(method_idx, true) << "' on a null object reference";
448*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
449*795d594fSAndroid Build Coastguard Worker }
450*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx,InvokeType type)451*795d594fSAndroid Build Coastguard Worker void ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx, InvokeType type) {
452*795d594fSAndroid Build Coastguard Worker const DexFile& dex_file = *Thread::Current()->GetCurrentMethod(nullptr)->GetDexFile();
453*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccessImpl(method_idx, dex_file, type);
454*795d594fSAndroid Build Coastguard Worker }
455*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerExceptionForMethodAccess(ArtMethod * method,InvokeType type)456*795d594fSAndroid Build Coastguard Worker void ThrowNullPointerExceptionForMethodAccess(ArtMethod* method, InvokeType type) {
457*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccessImpl(method->GetDexMethodIndex(),
458*795d594fSAndroid Build Coastguard Worker *method->GetDexFile(),
459*795d594fSAndroid Build Coastguard Worker type);
460*795d594fSAndroid Build Coastguard Worker }
461*795d594fSAndroid Build Coastguard Worker
IsValidReadBarrierImplicitCheck(uintptr_t addr)462*795d594fSAndroid Build Coastguard Worker static bool IsValidReadBarrierImplicitCheck(uintptr_t addr) {
463*795d594fSAndroid Build Coastguard Worker DCHECK(gUseReadBarrier);
464*795d594fSAndroid Build Coastguard Worker uint32_t monitor_offset = mirror::Object::MonitorOffset().Uint32Value();
465*795d594fSAndroid Build Coastguard Worker if (kUseBakerReadBarrier &&
466*795d594fSAndroid Build Coastguard Worker (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64)) {
467*795d594fSAndroid Build Coastguard Worker constexpr uint32_t gray_byte_position = LockWord::kReadBarrierStateShift / kBitsPerByte;
468*795d594fSAndroid Build Coastguard Worker monitor_offset += gray_byte_position;
469*795d594fSAndroid Build Coastguard Worker }
470*795d594fSAndroid Build Coastguard Worker return addr == monitor_offset;
471*795d594fSAndroid Build Coastguard Worker }
472*795d594fSAndroid Build Coastguard Worker
IsValidImplicitCheck(uintptr_t addr,const Instruction & instr)473*795d594fSAndroid Build Coastguard Worker static bool IsValidImplicitCheck(uintptr_t addr, const Instruction& instr)
474*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
475*795d594fSAndroid Build Coastguard Worker if (!CanDoImplicitNullCheckOn(addr)) {
476*795d594fSAndroid Build Coastguard Worker return false;
477*795d594fSAndroid Build Coastguard Worker }
478*795d594fSAndroid Build Coastguard Worker
479*795d594fSAndroid Build Coastguard Worker switch (instr.Opcode()) {
480*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_DIRECT:
481*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_DIRECT_RANGE:
482*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_VIRTUAL:
483*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_VIRTUAL_RANGE:
484*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_INTERFACE:
485*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_INTERFACE_RANGE:
486*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_POLYMORPHIC:
487*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_POLYMORPHIC_RANGE:
488*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_SUPER:
489*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_SUPER_RANGE: {
490*795d594fSAndroid Build Coastguard Worker // Without inlining, we could just check that the offset is the class offset.
491*795d594fSAndroid Build Coastguard Worker // However, when inlining, the compiler can (validly) merge the null check with a field access
492*795d594fSAndroid Build Coastguard Worker // on the same object. Note that the stack map at the NPE will reflect the invoke's location,
493*795d594fSAndroid Build Coastguard Worker // which is the caller.
494*795d594fSAndroid Build Coastguard Worker return true;
495*795d594fSAndroid Build Coastguard Worker }
496*795d594fSAndroid Build Coastguard Worker
497*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_OBJECT:
498*795d594fSAndroid Build Coastguard Worker if (gUseReadBarrier && IsValidReadBarrierImplicitCheck(addr)) {
499*795d594fSAndroid Build Coastguard Worker return true;
500*795d594fSAndroid Build Coastguard Worker }
501*795d594fSAndroid Build Coastguard Worker FALLTHROUGH_INTENDED;
502*795d594fSAndroid Build Coastguard Worker case Instruction::IGET:
503*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_WIDE:
504*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_BOOLEAN:
505*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_BYTE:
506*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_CHAR:
507*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_SHORT:
508*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT:
509*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_WIDE:
510*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_OBJECT:
511*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_BOOLEAN:
512*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_BYTE:
513*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_CHAR:
514*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_SHORT: {
515*795d594fSAndroid Build Coastguard Worker // We might be doing an implicit null check with an offset that doesn't correspond
516*795d594fSAndroid Build Coastguard Worker // to the instruction, for example with two field accesses and the first one being
517*795d594fSAndroid Build Coastguard Worker // eliminated or re-ordered.
518*795d594fSAndroid Build Coastguard Worker return true;
519*795d594fSAndroid Build Coastguard Worker }
520*795d594fSAndroid Build Coastguard Worker
521*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_OBJECT:
522*795d594fSAndroid Build Coastguard Worker if (gUseReadBarrier && IsValidReadBarrierImplicitCheck(addr)) {
523*795d594fSAndroid Build Coastguard Worker return true;
524*795d594fSAndroid Build Coastguard Worker }
525*795d594fSAndroid Build Coastguard Worker FALLTHROUGH_INTENDED;
526*795d594fSAndroid Build Coastguard Worker case Instruction::AGET:
527*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_WIDE:
528*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_BOOLEAN:
529*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_BYTE:
530*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_CHAR:
531*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_SHORT:
532*795d594fSAndroid Build Coastguard Worker case Instruction::APUT:
533*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_WIDE:
534*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_OBJECT:
535*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_BOOLEAN:
536*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_BYTE:
537*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_CHAR:
538*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_SHORT:
539*795d594fSAndroid Build Coastguard Worker case Instruction::FILL_ARRAY_DATA:
540*795d594fSAndroid Build Coastguard Worker case Instruction::ARRAY_LENGTH: {
541*795d594fSAndroid Build Coastguard Worker // The length access should crash. We currently do not do implicit checks on
542*795d594fSAndroid Build Coastguard Worker // the array access itself.
543*795d594fSAndroid Build Coastguard Worker return (addr == 0u) || (addr == mirror::Array::LengthOffset().Uint32Value());
544*795d594fSAndroid Build Coastguard Worker }
545*795d594fSAndroid Build Coastguard Worker
546*795d594fSAndroid Build Coastguard Worker default: {
547*795d594fSAndroid Build Coastguard Worker // We have covered all the cases where an NPE could occur.
548*795d594fSAndroid Build Coastguard Worker // Note that this must be kept in sync with the compiler, and adding
549*795d594fSAndroid Build Coastguard Worker // any new way to do implicit checks in the compiler should also update
550*795d594fSAndroid Build Coastguard Worker // this code.
551*795d594fSAndroid Build Coastguard Worker return false;
552*795d594fSAndroid Build Coastguard Worker }
553*795d594fSAndroid Build Coastguard Worker }
554*795d594fSAndroid Build Coastguard Worker }
555*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerExceptionFromDexPC(bool check_address,uintptr_t addr)556*795d594fSAndroid Build Coastguard Worker void ThrowNullPointerExceptionFromDexPC(bool check_address, uintptr_t addr) {
557*795d594fSAndroid Build Coastguard Worker uint32_t throw_dex_pc;
558*795d594fSAndroid Build Coastguard Worker ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc);
559*795d594fSAndroid Build Coastguard Worker CodeItemInstructionAccessor accessor(method->DexInstructions());
560*795d594fSAndroid Build Coastguard Worker CHECK_LT(throw_dex_pc, accessor.InsnsSizeInCodeUnits());
561*795d594fSAndroid Build Coastguard Worker const Instruction& instr = accessor.InstructionAt(throw_dex_pc);
562*795d594fSAndroid Build Coastguard Worker if (check_address && !IsValidImplicitCheck(addr, instr)) {
563*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
564*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Invalid address for an implicit NullPointerException check: "
565*795d594fSAndroid Build Coastguard Worker << "0x" << std::hex << addr << std::dec
566*795d594fSAndroid Build Coastguard Worker << ", at "
567*795d594fSAndroid Build Coastguard Worker << instr.DumpString(dex_file)
568*795d594fSAndroid Build Coastguard Worker << " in "
569*795d594fSAndroid Build Coastguard Worker << method->PrettyMethod();
570*795d594fSAndroid Build Coastguard Worker }
571*795d594fSAndroid Build Coastguard Worker
572*795d594fSAndroid Build Coastguard Worker switch (instr.Opcode()) {
573*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_DIRECT:
574*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kDirect);
575*795d594fSAndroid Build Coastguard Worker break;
576*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_DIRECT_RANGE:
577*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kDirect);
578*795d594fSAndroid Build Coastguard Worker break;
579*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_VIRTUAL:
580*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kVirtual);
581*795d594fSAndroid Build Coastguard Worker break;
582*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_VIRTUAL_RANGE:
583*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kVirtual);
584*795d594fSAndroid Build Coastguard Worker break;
585*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_SUPER:
586*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kSuper);
587*795d594fSAndroid Build Coastguard Worker break;
588*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_SUPER_RANGE:
589*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kSuper);
590*795d594fSAndroid Build Coastguard Worker break;
591*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_INTERFACE:
592*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kInterface);
593*795d594fSAndroid Build Coastguard Worker break;
594*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_INTERFACE_RANGE:
595*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kInterface);
596*795d594fSAndroid Build Coastguard Worker break;
597*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_POLYMORPHIC:
598*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_45cc(), kVirtual);
599*795d594fSAndroid Build Coastguard Worker break;
600*795d594fSAndroid Build Coastguard Worker case Instruction::INVOKE_POLYMORPHIC_RANGE:
601*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForMethodAccess(instr.VRegB_4rcc(), kVirtual);
602*795d594fSAndroid Build Coastguard Worker break;
603*795d594fSAndroid Build Coastguard Worker case Instruction::IGET:
604*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_WIDE:
605*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_OBJECT:
606*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_BOOLEAN:
607*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_BYTE:
608*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_CHAR:
609*795d594fSAndroid Build Coastguard Worker case Instruction::IGET_SHORT: {
610*795d594fSAndroid Build Coastguard Worker ArtField* field =
611*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker()->ResolveField(instr.VRegC_22c(), method, false);
612*795d594fSAndroid Build Coastguard Worker Thread::Current()->ClearException(); // Resolution may fail, ignore.
613*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForFieldAccess(field, method, /* is_read= */ true);
614*795d594fSAndroid Build Coastguard Worker break;
615*795d594fSAndroid Build Coastguard Worker }
616*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT:
617*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_WIDE:
618*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_OBJECT:
619*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_BOOLEAN:
620*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_BYTE:
621*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_CHAR:
622*795d594fSAndroid Build Coastguard Worker case Instruction::IPUT_SHORT: {
623*795d594fSAndroid Build Coastguard Worker ArtField* field = Runtime::Current()->GetClassLinker()->ResolveField(
624*795d594fSAndroid Build Coastguard Worker instr.VRegC_22c(), method, /* is_static= */ false);
625*795d594fSAndroid Build Coastguard Worker Thread::Current()->ClearException(); // Resolution may fail, ignore.
626*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForFieldAccess(field, method, /* is_read= */ false);
627*795d594fSAndroid Build Coastguard Worker break;
628*795d594fSAndroid Build Coastguard Worker }
629*795d594fSAndroid Build Coastguard Worker case Instruction::AGET:
630*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_WIDE:
631*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_OBJECT:
632*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_BOOLEAN:
633*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_BYTE:
634*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_CHAR:
635*795d594fSAndroid Build Coastguard Worker case Instruction::AGET_SHORT:
636*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr,
637*795d594fSAndroid Build Coastguard Worker "Attempt to read from null array");
638*795d594fSAndroid Build Coastguard Worker break;
639*795d594fSAndroid Build Coastguard Worker case Instruction::APUT:
640*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_WIDE:
641*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_OBJECT:
642*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_BOOLEAN:
643*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_BYTE:
644*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_CHAR:
645*795d594fSAndroid Build Coastguard Worker case Instruction::APUT_SHORT:
646*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr,
647*795d594fSAndroid Build Coastguard Worker "Attempt to write to null array");
648*795d594fSAndroid Build Coastguard Worker break;
649*795d594fSAndroid Build Coastguard Worker case Instruction::ARRAY_LENGTH:
650*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr,
651*795d594fSAndroid Build Coastguard Worker "Attempt to get length of null array");
652*795d594fSAndroid Build Coastguard Worker break;
653*795d594fSAndroid Build Coastguard Worker case Instruction::FILL_ARRAY_DATA: {
654*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr,
655*795d594fSAndroid Build Coastguard Worker "Attempt to write to null array");
656*795d594fSAndroid Build Coastguard Worker break;
657*795d594fSAndroid Build Coastguard Worker }
658*795d594fSAndroid Build Coastguard Worker case Instruction::MONITOR_ENTER:
659*795d594fSAndroid Build Coastguard Worker case Instruction::MONITOR_EXIT: {
660*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr,
661*795d594fSAndroid Build Coastguard Worker "Attempt to do a synchronize operation on a null object");
662*795d594fSAndroid Build Coastguard Worker break;
663*795d594fSAndroid Build Coastguard Worker }
664*795d594fSAndroid Build Coastguard Worker default: {
665*795d594fSAndroid Build Coastguard Worker const DexFile* dex_file = method->GetDexFile();
666*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "NullPointerException at an unexpected instruction: "
667*795d594fSAndroid Build Coastguard Worker << instr.DumpString(dex_file)
668*795d594fSAndroid Build Coastguard Worker << " in "
669*795d594fSAndroid Build Coastguard Worker << method->PrettyMethod();
670*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
671*795d594fSAndroid Build Coastguard Worker }
672*795d594fSAndroid Build Coastguard Worker }
673*795d594fSAndroid Build Coastguard Worker }
674*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerException(const char * msg)675*795d594fSAndroid Build Coastguard Worker void ThrowNullPointerException(const char* msg) {
676*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;", nullptr, msg);
677*795d594fSAndroid Build Coastguard Worker }
678*795d594fSAndroid Build Coastguard Worker
ThrowNullPointerException()679*795d594fSAndroid Build Coastguard Worker void ThrowNullPointerException() {
680*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/NullPointerException;");
681*795d594fSAndroid Build Coastguard Worker }
682*795d594fSAndroid Build Coastguard Worker
683*795d594fSAndroid Build Coastguard Worker // ReadOnlyBufferException
684*795d594fSAndroid Build Coastguard Worker
ThrowReadOnlyBufferException()685*795d594fSAndroid Build Coastguard Worker void ThrowReadOnlyBufferException() {
686*795d594fSAndroid Build Coastguard Worker Thread::Current()->ThrowNewException("Ljava/nio/ReadOnlyBufferException;", nullptr);
687*795d594fSAndroid Build Coastguard Worker }
688*795d594fSAndroid Build Coastguard Worker
689*795d594fSAndroid Build Coastguard Worker // RuntimeException
690*795d594fSAndroid Build Coastguard Worker
ThrowRuntimeException(const char * fmt,...)691*795d594fSAndroid Build Coastguard Worker void ThrowRuntimeException(const char* fmt, ...) {
692*795d594fSAndroid Build Coastguard Worker va_list args;
693*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
694*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/RuntimeException;", nullptr, fmt, &args);
695*795d594fSAndroid Build Coastguard Worker va_end(args);
696*795d594fSAndroid Build Coastguard Worker }
697*795d594fSAndroid Build Coastguard Worker
698*795d594fSAndroid Build Coastguard Worker // SecurityException
699*795d594fSAndroid Build Coastguard Worker
ThrowSecurityException(const char * fmt,...)700*795d594fSAndroid Build Coastguard Worker void ThrowSecurityException(const char* fmt, ...) {
701*795d594fSAndroid Build Coastguard Worker va_list args;
702*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
703*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/SecurityException;", nullptr, fmt, &args);
704*795d594fSAndroid Build Coastguard Worker va_end(args);
705*795d594fSAndroid Build Coastguard Worker }
706*795d594fSAndroid Build Coastguard Worker
707*795d594fSAndroid Build Coastguard Worker // Stack overflow.
708*795d594fSAndroid Build Coastguard Worker
709*795d594fSAndroid Build Coastguard Worker template <StackType stack_type>
ThrowStackOverflowError(Thread * self)710*795d594fSAndroid Build Coastguard Worker void ThrowStackOverflowError(Thread* self) {
711*795d594fSAndroid Build Coastguard Worker if (self->IsHandlingStackOverflow<stack_type>()) {
712*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Recursive stack overflow.";
713*795d594fSAndroid Build Coastguard Worker // We don't fail here because SetStackEndForStackOverflow will print better diagnostics.
714*795d594fSAndroid Build Coastguard Worker }
715*795d594fSAndroid Build Coastguard Worker
716*795d594fSAndroid Build Coastguard Worker // Allow space on the stack for constructor to execute.
717*795d594fSAndroid Build Coastguard Worker self->SetStackEndForStackOverflow<stack_type>();
718*795d594fSAndroid Build Coastguard Worker
719*795d594fSAndroid Build Coastguard Worker // Remove the stack overflow protection if it is set up.
720*795d594fSAndroid Build Coastguard Worker bool implicit_stack_check = Runtime::Current()->GetImplicitStackOverflowChecks();
721*795d594fSAndroid Build Coastguard Worker if (implicit_stack_check) {
722*795d594fSAndroid Build Coastguard Worker if (!self->UnprotectStack<stack_type>()) {
723*795d594fSAndroid Build Coastguard Worker LOG(ERROR) << "Unable to remove stack protection for stack overflow";
724*795d594fSAndroid Build Coastguard Worker }
725*795d594fSAndroid Build Coastguard Worker }
726*795d594fSAndroid Build Coastguard Worker
727*795d594fSAndroid Build Coastguard Worker // Avoid running Java code for exception initialization.
728*795d594fSAndroid Build Coastguard Worker // TODO: Checks to make this a bit less brittle.
729*795d594fSAndroid Build Coastguard Worker //
730*795d594fSAndroid Build Coastguard Worker // Note: This lambda is used to make sure the `StackOverflowError` intitialization code
731*795d594fSAndroid Build Coastguard Worker // does not increase the frame size of `ThrowStackOverflowError()` itself. It runs
732*795d594fSAndroid Build Coastguard Worker // with its own frame in the extended stack, which is especially important for modes
733*795d594fSAndroid Build Coastguard Worker // with larger stack sizes (e.g., ASAN).
734*795d594fSAndroid Build Coastguard Worker auto create_and_throw = [self]() REQUIRES_SHARED(Locks::mutator_lock_) NO_INLINE {
735*795d594fSAndroid Build Coastguard Worker std::string msg("stack size ");
736*795d594fSAndroid Build Coastguard Worker msg += PrettySize(self->GetUsableStackSize<stack_type>());
737*795d594fSAndroid Build Coastguard Worker
738*795d594fSAndroid Build Coastguard Worker ScopedObjectAccessUnchecked soa(self);
739*795d594fSAndroid Build Coastguard Worker StackHandleScope<1u> hs(self);
740*795d594fSAndroid Build Coastguard Worker
741*795d594fSAndroid Build Coastguard Worker // Allocate an uninitialized object.
742*795d594fSAndroid Build Coastguard Worker DCHECK(WellKnownClasses::java_lang_StackOverflowError->IsInitialized());
743*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> exc = hs.NewHandle(
744*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_lang_StackOverflowError->AllocObject(self));
745*795d594fSAndroid Build Coastguard Worker if (exc == nullptr) {
746*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Could not allocate StackOverflowError object.";
747*795d594fSAndroid Build Coastguard Worker return;
748*795d594fSAndroid Build Coastguard Worker }
749*795d594fSAndroid Build Coastguard Worker
750*795d594fSAndroid Build Coastguard Worker // "Initialize".
751*795d594fSAndroid Build Coastguard Worker // StackOverflowError -> VirtualMachineError -> Error -> Throwable -> Object.
752*795d594fSAndroid Build Coastguard Worker // Only Throwable has "custom" fields:
753*795d594fSAndroid Build Coastguard Worker // String detailMessage.
754*795d594fSAndroid Build Coastguard Worker // Throwable cause (= this).
755*795d594fSAndroid Build Coastguard Worker // List<Throwable> suppressedExceptions (= Collections.emptyList()).
756*795d594fSAndroid Build Coastguard Worker // Object stackState;
757*795d594fSAndroid Build Coastguard Worker // StackTraceElement[] stackTrace;
758*795d594fSAndroid Build Coastguard Worker // Only Throwable has a non-empty constructor:
759*795d594fSAndroid Build Coastguard Worker // this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT;
760*795d594fSAndroid Build Coastguard Worker // fillInStackTrace();
761*795d594fSAndroid Build Coastguard Worker
762*795d594fSAndroid Build Coastguard Worker // detailMessage.
763*795d594fSAndroid Build Coastguard Worker {
764*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> s = mirror::String::AllocFromModifiedUtf8(self, msg.c_str());
765*795d594fSAndroid Build Coastguard Worker if (s == nullptr) {
766*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Could not throw new StackOverflowError because message allocation failed.";
767*795d594fSAndroid Build Coastguard Worker return;
768*795d594fSAndroid Build Coastguard Worker }
769*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_lang_Throwable_detailMessage
770*795d594fSAndroid Build Coastguard Worker ->SetObject</*kTransactionActive=*/ false>(exc.Get(), s);
771*795d594fSAndroid Build Coastguard Worker }
772*795d594fSAndroid Build Coastguard Worker
773*795d594fSAndroid Build Coastguard Worker // cause.
774*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_lang_Throwable_cause
775*795d594fSAndroid Build Coastguard Worker ->SetObject</*kTransactionActive=*/ false>(exc.Get(), exc.Get());
776*795d594fSAndroid Build Coastguard Worker
777*795d594fSAndroid Build Coastguard Worker // suppressedExceptions.
778*795d594fSAndroid Build Coastguard Worker {
779*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> j_u_c = WellKnownClasses::java_util_Collections.Get();
780*795d594fSAndroid Build Coastguard Worker DCHECK(j_u_c->IsInitialized());
781*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> empty_list =
782*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_util_Collections_EMPTY_LIST->GetObject(j_u_c);
783*795d594fSAndroid Build Coastguard Worker CHECK(empty_list != nullptr);
784*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_lang_Throwable_suppressedExceptions
785*795d594fSAndroid Build Coastguard Worker ->SetObject</*kTransactionActive=*/ false>(exc.Get(), empty_list);
786*795d594fSAndroid Build Coastguard Worker }
787*795d594fSAndroid Build Coastguard Worker
788*795d594fSAndroid Build Coastguard Worker // stackState is set as result of fillInStackTrace. fillInStackTrace calls
789*795d594fSAndroid Build Coastguard Worker // nativeFillInStackTrace.
790*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> stack_state_val = self->CreateInternalStackTrace(soa);
791*795d594fSAndroid Build Coastguard Worker if (stack_state_val != nullptr) {
792*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_lang_Throwable_stackState
793*795d594fSAndroid Build Coastguard Worker ->SetObject</*kTransactionActive=*/ false>(exc.Get(), stack_state_val);
794*795d594fSAndroid Build Coastguard Worker
795*795d594fSAndroid Build Coastguard Worker // stackTrace.
796*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> l_u_ea = WellKnownClasses::libcore_util_EmptyArray.Get();
797*795d594fSAndroid Build Coastguard Worker DCHECK(l_u_ea->IsInitialized());
798*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> empty_ste =
799*795d594fSAndroid Build Coastguard Worker WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT->GetObject(l_u_ea);
800*795d594fSAndroid Build Coastguard Worker CHECK(empty_ste != nullptr);
801*795d594fSAndroid Build Coastguard Worker WellKnownClasses::java_lang_Throwable_stackTrace
802*795d594fSAndroid Build Coastguard Worker ->SetObject</*kTransactionActive=*/ false>(exc.Get(), empty_ste);
803*795d594fSAndroid Build Coastguard Worker } else {
804*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Could not create stack trace.";
805*795d594fSAndroid Build Coastguard Worker // Note: we'll create an exception without stack state, which is valid.
806*795d594fSAndroid Build Coastguard Worker }
807*795d594fSAndroid Build Coastguard Worker
808*795d594fSAndroid Build Coastguard Worker // Throw the exception.
809*795d594fSAndroid Build Coastguard Worker self->SetException(exc->AsThrowable());
810*795d594fSAndroid Build Coastguard Worker };
811*795d594fSAndroid Build Coastguard Worker create_and_throw();
812*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
813*795d594fSAndroid Build Coastguard Worker
814*795d594fSAndroid Build Coastguard Worker self->ResetDefaultStackEnd<stack_type>(); // Return to default stack size.
815*795d594fSAndroid Build Coastguard Worker
816*795d594fSAndroid Build Coastguard Worker // And restore protection if implicit checks are on.
817*795d594fSAndroid Build Coastguard Worker if (implicit_stack_check) {
818*795d594fSAndroid Build Coastguard Worker self->ProtectStack<stack_type>();
819*795d594fSAndroid Build Coastguard Worker }
820*795d594fSAndroid Build Coastguard Worker }
821*795d594fSAndroid Build Coastguard Worker
822*795d594fSAndroid Build Coastguard Worker // Explicit instantiations to keep this definition separate to the declaration.
823*795d594fSAndroid Build Coastguard Worker template void ThrowStackOverflowError<StackType::kHardware>(Thread* self);
824*795d594fSAndroid Build Coastguard Worker
825*795d594fSAndroid Build Coastguard Worker // StringIndexOutOfBoundsException
826*795d594fSAndroid Build Coastguard Worker
ThrowStringIndexOutOfBoundsException(int index,int length)827*795d594fSAndroid Build Coastguard Worker void ThrowStringIndexOutOfBoundsException(int index, int length) {
828*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/StringIndexOutOfBoundsException;", nullptr,
829*795d594fSAndroid Build Coastguard Worker StringPrintf("length=%d; index=%d", length, index).c_str());
830*795d594fSAndroid Build Coastguard Worker }
831*795d594fSAndroid Build Coastguard Worker
832*795d594fSAndroid Build Coastguard Worker // UnsupportedOperationException
833*795d594fSAndroid Build Coastguard Worker
ThrowUnsupportedOperationException()834*795d594fSAndroid Build Coastguard Worker void ThrowUnsupportedOperationException() {
835*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/UnsupportedOperationException;");
836*795d594fSAndroid Build Coastguard Worker }
837*795d594fSAndroid Build Coastguard Worker
838*795d594fSAndroid Build Coastguard Worker // VerifyError
839*795d594fSAndroid Build Coastguard Worker
ThrowVerifyError(ObjPtr<mirror::Class> referrer,const char * fmt,...)840*795d594fSAndroid Build Coastguard Worker void ThrowVerifyError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) {
841*795d594fSAndroid Build Coastguard Worker va_list args;
842*795d594fSAndroid Build Coastguard Worker va_start(args, fmt);
843*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/VerifyError;", referrer, fmt, &args);
844*795d594fSAndroid Build Coastguard Worker va_end(args);
845*795d594fSAndroid Build Coastguard Worker }
846*795d594fSAndroid Build Coastguard Worker
847*795d594fSAndroid Build Coastguard Worker // WrongMethodTypeException
848*795d594fSAndroid Build Coastguard Worker
ThrowWrongMethodTypeException(ObjPtr<mirror::MethodType> expected_type,ObjPtr<mirror::MethodType> actual_type)849*795d594fSAndroid Build Coastguard Worker void ThrowWrongMethodTypeException(ObjPtr<mirror::MethodType> expected_type,
850*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::MethodType> actual_type) {
851*795d594fSAndroid Build Coastguard Worker ThrowWrongMethodTypeException(expected_type->PrettyDescriptor(), actual_type->PrettyDescriptor());
852*795d594fSAndroid Build Coastguard Worker }
853*795d594fSAndroid Build Coastguard Worker
ThrowWrongMethodTypeException(const std::string & expected_descriptor,const std::string & actual_descriptor)854*795d594fSAndroid Build Coastguard Worker void ThrowWrongMethodTypeException(const std::string& expected_descriptor,
855*795d594fSAndroid Build Coastguard Worker const std::string& actual_descriptor) {
856*795d594fSAndroid Build Coastguard Worker std::ostringstream msg;
857*795d594fSAndroid Build Coastguard Worker msg << "Expected " << expected_descriptor << " but was " << actual_descriptor;
858*795d594fSAndroid Build Coastguard Worker ThrowException("Ljava/lang/invoke/WrongMethodTypeException;", nullptr, msg.str().c_str());
859*795d594fSAndroid Build Coastguard Worker }
860*795d594fSAndroid Build Coastguard Worker
861*795d594fSAndroid Build Coastguard Worker } // namespace art
862