interpreter.cc revision 167436311a08a65dea28dda079a137893821c9c7
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License. 689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at 789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and 1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License. 1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */ 1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "interpreter.h" 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <math.h> 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "base/logging.h" 2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "class_linker-inl.h" 2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "common_throws.h" 2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "dex_file-inl.h" 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "dex_instruction.h" 2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "gc/card_table-inl.h" 2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "invoke_arg_array_builder.h" 2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "nth_caller_visitor.h" 2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/class.h" 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/class-inl.h" 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/field-inl.h" 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/abstract_method.h" 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/abstract_method-inl.h" 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/object-inl.h" 357562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include "mirror/object_array-inl.h" 367562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include "object_utils.h" 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "runtime_support.h" 3838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include "ScopedLocalRef.h" 3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "scoped_thread_state_change.h" 40fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include "thread.h" 41fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 42fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinusing namespace art::mirror; 43fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 44fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace art { 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace interpreter { 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const int32_t kMaxInt = std::numeric_limits<int32_t>::max(); 4933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const int32_t kMinInt = std::numeric_limits<int32_t>::min(); 5033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const int64_t kMaxLong = std::numeric_limits<int64_t>::max(); 5133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const int64_t kMinLong = std::numeric_limits<int64_t>::min(); 5233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh 5333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method, 5433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) 5533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 5633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh // In a runtime that's not started we intercept certain methods to avoid complicated dependency 5733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh // problems in core libraries. 5833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh std::string name(PrettyMethod(target_method)); 5933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") { 6033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str())); 6133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader(); 6233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(), 6333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh class_loader); 6433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: " 6533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh << PrettyDescriptor(descriptor); 6633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh result->SetL(found); 6733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh } else if (name == "java.lang.Object java.lang.Class.newInstance()") { 6833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); 6933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh AbstractMethod* c = klass->FindDeclaredDirectMethod("<init>", "()V"); 7033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh CHECK(c != NULL); 7133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh Object* obj = klass->AllocObject(self); 7233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh CHECK(obj != NULL); 7333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh EnterInterpreterFromInvoke(self, c, obj, NULL, NULL); 7433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh result->SetL(obj); 7533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh } else if (name == "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") { 7633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail 7733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh // going the reflective Dex way. 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Field* found = NULL; 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project FieldHelper fh; 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ObjectArray<Field>* fields = klass->GetIFields(); 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Field* f = fields->Get(i); 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fh.ChangeField(f); 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (name->Equals(fh.GetName())) { 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project found = f; 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 90c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (found == NULL) { 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fields = klass->GetSFields(); 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Field* f = fields->Get(i); 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fh.ChangeField(f); 95be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent if (name->Equals(fh.GetName())) { 96be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent found = f; 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 99c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 100a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent CHECK(found != NULL) 101a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent << "Failed to find field in Class.getDeclaredField in un-started runtime. name=" 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project << name->ToModifiedUtf8() << " class=" << PrettyDescriptor(klass); 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // TODO: getDeclaredField calls GetType once the field is found to ensure a 10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // NoClassDefFoundError is thrown if the field's type cannot be resolved. 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(found); 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)") { 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Special case array copying without initializing System. 108c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent Class* ctype = shadow_frame->GetVRegReference(arg_offset)->GetClass()->GetComponentType(); 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jint srcPos = shadow_frame->GetVReg(arg_offset + 1); 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jint dstPos = shadow_frame->GetVReg(arg_offset + 3); 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jint length = shadow_frame->GetVReg(arg_offset + 4); 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!ctype->IsPrimitive()) { 113be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent ObjectArray<Object>* src = shadow_frame->GetVRegReference(arg_offset)->AsObjectArray<Object>(); 114be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent ObjectArray<Object>* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<Object>(); 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (jint i = 0; i < length; ++i) { 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst->Set(dstPos + i, src->Get(srcPos + i)); 117c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 118a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent } else if (ctype->IsPrimitiveChar()) { 119a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent CharArray* src = shadow_frame->GetVRegReference(arg_offset)->AsCharArray(); 12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CharArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray(); 12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (jint i = 0; i < length; ++i) { 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst->Set(dstPos + i, src->Get(srcPos + i)); 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (ctype->IsPrimitiveInt()) { 12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IntArray* src = shadow_frame->GetVRegReference(arg_offset)->AsIntArray(); 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IntArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsIntArray(); 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (jint i = 0; i < length; ++i) { 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dst->Set(dstPos + i, src->Get(srcPos + i)); 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project UNIMPLEMENTED(FATAL) << "System.arraycopy of unexpected type: " << PrettyDescriptor(ctype); 13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Not special, continue with regular interpreter execution. 13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetJ(EnterInterpreterFromInterpreter(self, shadow_frame).GetJ()); 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Hand select a number of methods to be run in a not yet started runtime without using JNI. 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void UnstartedRuntimeJni(Thread* self, AbstractMethod* method, 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* receiver, uint32_t* args, JValue* result) 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project std::string name(PrettyMethod(method)); 144c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") { 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(NULL); 14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") { 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project NthCallerVisitor visitor(self, 3); 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project visitor.WalkStack(); 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(visitor.caller->GetDeclaringClass()); 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "double java.lang.Math.log(double)") { 151be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent JValue value; 152be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetD(log(value.GetD())); 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "java.lang.String java.lang.Class.getNameNative()") { 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(receiver->AsClass()->ComputeName()); 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "int java.lang.Float.floatToRawIntBits(float)") { 1571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result->SetI(args[0]); 1581dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent } else if (name == "float java.lang.Float.intBitsToFloat(int)") { 15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetI(args[0]); 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "double java.lang.Math.exp(double)") { 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project JValue value; 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetD(exp(value.GetD())); 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "java.lang.Object java.lang.Object.internalClone()") { 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(receiver->Clone(self)); 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "void java.lang.Object.notifyAll()") { 16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project receiver->NotifyAll(self); 16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "int java.lang.String.compareTo(java.lang.String)") { 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project String* rhs = reinterpret_cast<Object*>(args[0])->AsString(); 17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(rhs != NULL); 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetI(receiver->AsString()->CompareTo(rhs)); 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "java.lang.String java.lang.String.intern()") { 173fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin result->SetL(receiver->AsString()->Intern()); 174fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin } else if (name == "int java.lang.String.fastIndexOf(int, int)") { 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1])); 17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") { 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(Array::CreateMultiArray(self, reinterpret_cast<Object*>(args[0])->AsClass(), reinterpret_cast<Object*>(args[1])->AsIntArray())); 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") { 17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedObjectAccessUnchecked soa(self); 18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa))); 181fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") { 18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetJ(JNI_TRUE); 183c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") { 184fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin Object* obj = reinterpret_cast<Object*>(args[0]); 18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jint expectedValue = args[3]; 18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jint newValue = args[4]; 188fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin byte* raw_addr = reinterpret_cast<byte*>(obj) + offset; 18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr); 19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // Note: android_atomic_release_cas() returns 0 on success, not failure. 19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int r = android_atomic_release_cas(expectedValue, newValue, address); 192c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent result->SetZ(r == 0); 193c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { 194fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin Object* obj = reinterpret_cast<Object*>(args[0]); 195fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin Object* newValue = reinterpret_cast<Object*>(args[3]); 196c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent obj->SetFieldObject(MemberOffset((static_cast<uint64_t>(args[2]) << 32) | args[1]), newValue, false); 197c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 198fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin LOG(FATAL) << "Attempt to invoke native method in non-started runtime: " << name; 199c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 202fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic void InterpreterJni(Thread* self, AbstractMethod* method, StringPiece shorty, 20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* receiver, uint32_t* args, JValue* result) 204fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 205fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 206fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin // it should be removed and JNI compiled stubs used instead. 207fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin ScopedObjectAccessUnchecked soa(self); 20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (method->IsStatic()) { 209c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (shorty == "L") { 210c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent typedef jobject (fnptr)(JNIEnv*, jclass); 211c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 21434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent jobject jresult; 21534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent { 216be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent ScopedThreadStateChange tsc(self, kNative); 217d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent jresult = fn(soa.Env(), klass.get()); 218d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 219be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent result->SetL(soa.Decode<Object*>(jresult)); 2202beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent } else if (shorty == "V") { 221be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent typedef void (fnptr)(JNIEnv*, jclass); 22234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 2231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedLocalRef<jclass> klass(soa.Env(), 2241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 2251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedThreadStateChange tsc(self, kNative); 2261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent fn(soa.Env(), klass.get()); 2271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else if (shorty == "Z") { 2281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent typedef jboolean (fnptr)(JNIEnv*, jclass); 2291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 2301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedLocalRef<jclass> klass(soa.Env(), 2311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 23334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result->SetZ(fn(soa.Env(), klass.get())); 23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "BI") { 23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef jbyte (fnptr)(JNIEnv*, jclass, jint); 23634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetB(fn(soa.Env(), klass.get(), args[0])); 24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "II") { 24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef jint (fnptr)(JNIEnv*, jclass, jint); 24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetI(fn(soa.Env(), klass.get(), args[0])); 24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "LL") { 249c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent typedef jobject (fnptr)(JNIEnv*, jclass, jobject); 25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg0(soa.Env(), 25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project jobject jresult; 25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 2582c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi jresult = fn(soa.Env(), klass.get(), arg0.get()); 25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetL(soa.Decode<Object*>(jresult)); 261c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else if (shorty == "IIZ") { 26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean); 26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "ILI") { 26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint); 27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg0(soa.Env(), 27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "SIZ") { 27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean); 27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "VIZ") { 28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean); 28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fn(soa.Env(), klass.get(), args[0], args[1]); 29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "ZLL") { 29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject); 29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 295d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg0(soa.Env(), 29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg1(soa.Env(), 29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 300fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin ScopedThreadStateChange tsc(self, kNative); 301fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 302c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else if (shorty == "ZILL") { 303c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject); 304c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg1(soa.Env(), 30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg2(soa.Env(), 31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "VILII") { 31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint); 31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 317d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg1(soa.Env(), 31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedThreadStateChange tsc(self, kNative); 32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (shorty == "VLILII") { 32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jclass> klass(soa.Env(), 32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg0(soa.Env(), 32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ScopedLocalRef<jobject> arg2(soa.Env(), 330f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 3311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedThreadStateChange tsc(self, kNative); 3321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 3331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 3341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 3351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent << " shorty: " << shorty; 3361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 337f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent } else { 338f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent if (shorty == "L") { 3391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent typedef jobject (fnptr)(JNIEnv*, jobject); 34033797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 3411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedLocalRef<jobject> rcvr(soa.Env(), 3421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent soa.AddLocalReference<jobject>(receiver)); 34338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent jobject jresult; 3442b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent { 3452b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent ScopedThreadStateChange tsc(self, kNative); 3462b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent jresult = fn(soa.Env(), rcvr.get()); 3472b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent } 3482b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent result->SetL(soa.Decode<Object*>(jresult)); 3492b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent } else if (shorty == "LL") { 3501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent typedef jobject (fnptr)(JNIEnv*, jobject, jobject); 3511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 3521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedLocalRef<jobject> rcvr(soa.Env(), 353d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent soa.AddLocalReference<jobject>(receiver)); 3541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ScopedLocalRef<jobject> arg0(soa.Env(), 3551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 35638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent jobject jresult; 3576100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent { 3582b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent ScopedThreadStateChange tsc(self, kNative); 3591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 3601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 3611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 3621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result->SetL(soa.Decode<Object*>(jresult)); 3632b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent ScopedThreadStateChange tsc(self, kNative); 3642b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent } else if (shorty == "III") { 365f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent typedef jint (fnptr)(JNIEnv*, jobject, jint, jint); 36634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 3672b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent ScopedLocalRef<jobject> rcvr(soa.Env(), 36834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent soa.AddLocalReference<jobject>(receiver)); 3692b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent ScopedThreadStateChange tsc(self, kNative); 37034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project << " shorty: " << shorty; 37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { 37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ref->MonitorEnter(self); 38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { 38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ref->MonitorExit(self); 38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame, 38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const DecodedInstruction& dec_insn, InvokeType type, bool is_range, 388f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent JValue* result) 389f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 390f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent Object* receiver; 3911dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent if (type == kStatic) { 39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project receiver = NULL; 39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project receiver = shadow_frame.GetVRegReference(dec_insn.vC); 3951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 3962c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi uint32_t method_idx = dec_insn.vB; 3972c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver, 3982c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi shadow_frame.GetMethod(), self, true, 39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project type); 40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(target_method == NULL)) { 40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(self->IsExceptionPending()); 4021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result->SetJ(0); 40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mh.ChangeMethod(target_method); 40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const DexFile::CodeItem* code_item = mh.GetCodeItem(); 40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint16_t num_regs; 40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint16_t num_ins; 41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (code_item != NULL) { 41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project num_regs = code_item->registers_size_; 41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project num_ins = code_item->ins_size_; 41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (target_method->IsAbstract()) { 41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;", 41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project "abstract method \"%s\"", PrettyMethod(target_method).c_str()); 41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DCHECK(target_method->IsNative() || target_method->IsProxyMethod()); 42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (!target_method->IsStatic()) { 42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project num_regs++; 4231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent num_ins++; 4241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 4251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 4261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent 4271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Runtime* runtime = Runtime::Current(); 4281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent UniquePtr<ShadowFrame> new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, 4291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent target_method, 0)); 43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t cur_reg = num_regs - num_ins; 431c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (receiver != NULL) { 4322c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi new_shadow_frame->SetVRegReference(cur_reg, receiver); 4332c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi ++cur_reg; 4342c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi } 4352c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi 436c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent size_t arg_offset = (receiver == NULL) ? 0 : 1; 43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const char* shorty = mh.GetShorty(); 43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) { 43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project size_t arg_pos = is_range ? dec_insn.vC + arg_offset : dec_insn.arg[arg_offset]; 44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project switch (shorty[shorty_pos + 1]) { 44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case 'L': { 44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* o = shadow_frame.GetVRegReference(arg_pos); 44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project new_shadow_frame->SetVRegReference(cur_reg, o); 44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case 'J': case 'D': { 448f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | 449f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); 450f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent new_shadow_frame->SetVRegLong(cur_reg, wide_value); 45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project cur_reg++; 45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project arg_offset++; 45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project default: 45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos)); 45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 45889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (LIKELY(runtime->IsStarted())) { 46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result->SetJ((target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame.get()).GetJ()); 46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project UnstartedRuntimeInvoke(self, target_method, new_shadow_frame.get(), result, num_regs - num_ins); 46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 466be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent mh.ChangeMethod(shadow_frame.GetMethod()); 46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 468be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent 469be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentstatic void DoFieldGet(Thread* self, ShadowFrame& shadow_frame, 470be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent const DecodedInstruction& dec_insn, FindFieldType find_type, 471be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent Primitive::Type field_type) 4721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead); 47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC; 47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project find_type, Primitive::FieldSize(field_type)); 477be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent if (LIKELY(f != NULL)) { 478be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent Object* obj; 479be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent if (is_static) { 48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project obj = f->GetDeclaringClass(); 48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project obj = shadow_frame.GetVRegReference(dec_insn.vB); 48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(obj == NULL)) { 484be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true); 485be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return; 486be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent } 487be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent } 488be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent switch (field_type) { 489be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent case Primitive::kPrimBoolean: 490be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj)); 491be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent break; 4922beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent case Primitive::kPrimByte: 493be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj)); 4942beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent break; 495be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent case Primitive::kPrimChar: 496be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj)); 497be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent break; 4981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Primitive::kPrimShort: 499be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj)); 500be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent break; 501be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent case Primitive::kPrimInt: 502be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj)); 503be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent break; 504be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent case Primitive::kPrimLong: 505be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj)); 506be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent break; 5072beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent case Primitive::kPrimNot: 508be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, f->GetObject(obj)); 509be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent break; 510be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent default: 511be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent LOG(FATAL) << "Unreachable: " << field_type; 51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 514573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent} 51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoFieldPut(Thread* self, ShadowFrame& shadow_frame, 51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const DecodedInstruction& dec_insn, FindFieldType find_type, 51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Primitive::Type field_type) 519573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite); 52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC; 522573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project find_type, Primitive::FieldSize(field_type)); 5241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (LIKELY(f != NULL)) { 525573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent Object* obj; 526573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent if (is_static) { 52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project obj = f->GetDeclaringClass(); 52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project obj = shadow_frame.GetVRegReference(dec_insn.vB); 53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(obj == NULL)) { 5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), 532573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent f, false); 53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project switch (field_type) { 5371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Primitive::kPrimBoolean: 5381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA)); 5391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 5401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Primitive::kPrimByte: 5411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA)); 5421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 5431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Primitive::kPrimChar: 54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA)); 54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Primitive::kPrimShort: 54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA)); 54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Primitive::kPrimInt: 55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA)); 55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Primitive::kPrimLong: 55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA)); 55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Primitive::kPrimNot: 55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project f->SetObj(obj, shadow_frame.GetVRegReference(dec_insn.vA)); 5579b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent break; 5589b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent default: 559d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent LOG(FATAL) << "Unreachable: " << field_type; 56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 5639b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent 56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoIntDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 565d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(divisor == 0)) { 567c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent ThrowArithmeticExceptionDivideByZero(self); 56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(result_reg, kMinInt); 57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(result_reg, dividend / divisor); 57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoIntRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(divisor == 0)) { 57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowArithmeticExceptionDivideByZero(self); 5791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(result_reg, 0); 58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(result_reg, dividend % divisor); 58389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 58489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoLongDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(divisor == 0)) { 58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowArithmeticExceptionDivideByZero(self); 59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegLong(result_reg, kMinLong); 59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegLong(result_reg, dividend / divisor); 59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoLongRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(divisor == 0)) { 60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowArithmeticExceptionDivideByZero(self); 60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 6022c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi shadow_frame.SetVRegLong(result_reg, 0); 60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegLong(result_reg, dividend % divisor); 60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 60889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ShadowFrame& shadow_frame, JValue result_register) 61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 61189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(!shadow_frame.HasReferenceArray())) { 61289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project LOG(FATAL) << "Invalid shadow frame for interpreter use"; 61389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return JValue(); 61489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 61589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project self->VerifyStack(); 61689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 61789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const uint16_t* insns = code_item->insns_; 61889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC()); 61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (inst->GetDexPc(insns) == 0) { // We are entering the method as opposed to deoptimizing.. 62089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(), 62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 0); 62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (true) { 62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CheckSuspend(self); 62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetDexPC(dex_pc); 62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(), 62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project dex_pc); 62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DecodedInstruction dec_insn(inst); 63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const bool kTracing = false; 63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (kTracing) { 63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define TRACE_LOG std::cerr 63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project TRACE_LOG << PrettyMethod(shadow_frame.GetMethod()) 63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project << StringPrintf("\n0x%x: ", inst->GetDexPc(insns)) 63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project << inst->DumpString(&mh.GetDexFile()) << "\n"; 63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project for (size_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) { 63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t raw_value = shadow_frame.GetVReg(i); 63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* ref_value = shadow_frame.GetVRegReference(i); 6391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent TRACE_LOG << StringPrintf(" vreg%d=0x%08X", i, raw_value); 64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ref_value != NULL) { 64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (ref_value->GetClass()->IsStringClass() && 64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ref_value->AsString()->GetCharArray() != NULL) { 64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project TRACE_LOG << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\""; 64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project TRACE_LOG << "/" << PrettyTypeOf(ref_value); 64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 64738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent } 648c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project TRACE_LOG << "\n"; 65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#undef TRACE_LOG 65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const Instruction* next_inst = inst->Next(); 65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project switch (dec_insn.opcode) { 65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::NOP: 6551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE: 65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE_FROM16: 65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE_16: 65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 66189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE_WIDE: 66289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE_WIDE_FROM16: 6631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::MOVE_WIDE_16: 6641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 666c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent case Instruction::MOVE_OBJECT: 6671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::MOVE_OBJECT_FROM16: 66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE_OBJECT_16: 669d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, shadow_frame.GetVRegReference(dec_insn.vB)); 67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::MOVE_RESULT: 67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, result_register.GetI()); 67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 674c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent case Instruction::MOVE_RESULT_WIDE: 675c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ()); 6761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 6771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::MOVE_RESULT_OBJECT: 6781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, result_register.GetL()); 6791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 6801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::MOVE_EXCEPTION: { 6811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Throwable* exception = self->GetException(NULL); 6821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent self->ClearException(); 683fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin shadow_frame.SetVRegReference(dec_insn.vA, exception); 684fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin break; 685c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 686c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent case Instruction::RETURN_VOID: { 687be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent JValue result; 688be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 689be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 690be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent result); 691be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return result; 692be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent } 693be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent case Instruction::RETURN: { 6942beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent JValue result; 6952beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent result.SetJ(0); 6962beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent result.SetI(shadow_frame.GetVReg(dec_insn.vA)); 6972beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 6982beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 6992beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent result); 700be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent return result; 701be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent } 70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::RETURN_WIDE: { 70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project JValue result; 7041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA)); 7051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 70634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 70734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result); 70834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return result; 70934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 71034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent case Instruction::RETURN_OBJECT: { 71134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent JValue result; 71234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result.SetJ(0); 713d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent result.SetL(shadow_frame.GetVRegReference(dec_insn.vA)); 714d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 71534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 71634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result); 71734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent return result; 71834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 71934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent case Instruction::CONST_4: { 72034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent int32_t val = static_cast<int32_t>(dec_insn.vB << 28) >> 28; 72134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent shadow_frame.SetVReg(dec_insn.vA, val); 72234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (val == 0) { 723d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, NULL); 724d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 725d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 726d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 727d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_16: { 728d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent int32_t val = static_cast<int16_t>(dec_insn.vB); 729d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVReg(dec_insn.vA, val); 730d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (val == 0) { 731d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, NULL); 732d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 733d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 734d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 735d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST: { 736d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent int32_t val = dec_insn.vB; 737fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin shadow_frame.SetVReg(dec_insn.vA, val); 738d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (val == 0) { 739d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, NULL); 740d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 741d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 742d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 743d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_HIGH16: { 744d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent int32_t val = dec_insn.vB << 16; 745d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVReg(dec_insn.vA, val); 746d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (val == 0) { 747d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, NULL); 748d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 749d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 750d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 751d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_WIDE_16: 752d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int16_t>(dec_insn.vB)); 753d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 754d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_WIDE_32: 755d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int32_t>(dec_insn.vB)); 756d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 757d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_WIDE: 758d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, dec_insn.vB_wide); 759d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 760d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_WIDE_HIGH16: 761d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegLong(dec_insn.vA, static_cast<uint64_t>(dec_insn.vB) << 48); 762d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 763d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_STRING: 764d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_STRING_JUMBO: { 765d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) { 766d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(), 767d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent true, true); 768d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 769d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent String* s = mh.ResolveString(dec_insn.vB); 770d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, s); 771d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 772d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 773d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::CONST_CLASS: { 774d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true); 775d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, c); 776d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 777d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent } 77834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent case Instruction::MONITOR_ENTER: { 77934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 78034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(obj == NULL)) { 78134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 78234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } else { 78334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent DoMonitorEnter(self, obj); 78434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 78534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent break; 78634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 787be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent case Instruction::MONITOR_EXIT: { 78834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 78934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(obj == NULL)) { 79034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 79134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } else { 79234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent DoMonitorExit(self, obj); 79334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 79434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent break; 79534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 79634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent case Instruction::CHECK_CAST: { 79734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true); 79834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(c == NULL)) { 79934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent CHECK(self->IsExceptionPending()); 80034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } else { 80134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 80234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) { 80334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ThrowClassCastException(c, obj->GetClass()); 80438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent } 80534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 80634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent break; 80734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 80834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent case Instruction::INSTANCE_OF: { 80934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent Class* c = ResolveVerifyAndClinit(dec_insn.vC, shadow_frame.GetMethod(), self, false, true); 810d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (UNLIKELY(c == NULL)) { 81134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent CHECK(self->IsExceptionPending()); 81234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } else { 813be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent Object* obj = shadow_frame.GetVRegReference(dec_insn.vB); 814be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0); 8152beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent } 8166100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent break; 8176100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent } 818d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent case Instruction::ARRAY_LENGTH: { 819d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent Object* array = shadow_frame.GetVRegReference(dec_insn.vB); 82034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(array == NULL)) { 82134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 82234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent break; 82389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 82489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, array->AsArray()->GetLength()); 8251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 82689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 82789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::NEW_INSTANCE: { 82889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true); 82989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegReference(dec_insn.vA, obj); 8301dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent break; 83189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 83289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::NEW_ARRAY: { 83389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t length = shadow_frame.GetVReg(dec_insn.vB); 83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true); 83589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegReference(dec_insn.vA, obj); 83689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 8379b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent } 8389b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent case Instruction::FILLED_NEW_ARRAY: 8399b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent case Instruction::FILLED_NEW_ARRAY_RANGE: { 8409b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE); 8419b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent int32_t length = dec_insn.vA; 8429b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent CHECK(is_range || length <= 5); 84389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(length < 0)) { 84434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ThrowNegativeArraySizeException(length); 84589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 84689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Class* arrayClass = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true); 84889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(arrayClass == NULL)) { 84989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(self->IsExceptionPending()); 85034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent break; 85189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 85289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(arrayClass->IsArrayClass()); 85334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent Class* componentClass = arrayClass->GetComponentType(); 85434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) { 85589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) { 85634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent ThrowRuntimeException("Bad filled array request for type %s", 857d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent PrettyDescriptor(componentClass).c_str()); 8581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } else { 859d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 8601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent "Ljava/lang/InternalError;", 8611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent "Found type %s; filled-new-array not implemented for anything but \'int\'", 8621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent PrettyDescriptor(componentClass).c_str()); 8631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 8641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 8651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 866d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent Object* newArray = Array::Alloc(self, arrayClass, length); 8671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (newArray != NULL) { 868d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent for (int32_t i = 0; i < length; ++i) { 869d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (is_range) { 870d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent if (componentClass->IsPrimitiveInt()) { 871c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.vC + i)); 8721dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent } else { 87389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.vC + i)); 87489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 87589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 87689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (componentClass->IsPrimitiveInt()) { 87789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.arg[i])); 87889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 879c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.arg[i])); 88089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 88134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 8821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 88334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent } 88438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent result_register.SetL(newArray); 885d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 8861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 8871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::CMPL_FLOAT: { 8881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent float val1 = shadow_frame.GetVRegFloat(dec_insn.vB); 8891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent float val2 = shadow_frame.GetVRegFloat(dec_insn.vC); 8901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t result; 8911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (val1 == val2) { 89234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = 0; 89389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (val1 > val2) { 89489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = 1; 89589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 896c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent result = -1; 89789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 89834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent shadow_frame.SetVReg(dec_insn.vA, result); 89989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 90089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 90189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::CMPG_FLOAT: { 90289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project float val1 = shadow_frame.GetVRegFloat(dec_insn.vB); 90389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project float val2 = shadow_frame.GetVRegFloat(dec_insn.vC); 90489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t result; 90589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (val1 == val2) { 90634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent result = 0; 90789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (val1 < val2) { 90889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = -1; 90944d9848d6656777a18019223e0d35f2fcc67719aEric Laurent } else { 9101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent result = 1; 91138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent } 91238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVReg(dec_insn.vA, result); 91338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 91444d9848d6656777a18019223e0d35f2fcc67719aEric Laurent } 91544d9848d6656777a18019223e0d35f2fcc67719aEric Laurent case Instruction::CMPL_DOUBLE: { 91689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project double val1 = shadow_frame.GetVRegDouble(dec_insn.vB); 917c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent double val2 = shadow_frame.GetVRegDouble(dec_insn.vC); 91889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t result; 91989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (val1 == val2) { 92089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = 0; 92189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (val1 > val2) { 92289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = 1; 92389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 92489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = -1; 92589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 92689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, result); 92789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 92889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 929c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 930c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent case Instruction::CMPG_DOUBLE: { 931c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent double val1 = shadow_frame.GetVRegDouble(dec_insn.vB); 932c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent double val2 = shadow_frame.GetVRegDouble(dec_insn.vC); 933fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin int32_t result; 934fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin if (val1 == val2) { 935c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent result = 0; 936c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else if (val1 < val2) { 937c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent result = -1; 938c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } else { 93989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = 1; 94089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 94189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, result); 94289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 94389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 94489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::CMP_LONG: { 9451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB); 9461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC); 94789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t result; 94889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (val1 > val2) { 94989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = 1; 95089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (val1 == val2) { 95189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = 0; 95289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 95389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project result = -1; 95489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 95589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, result); 95689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 95789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 95889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::THROW: { 95989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* exception = shadow_frame.GetVRegReference(dec_insn.vA); 96089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (exception == NULL) { 96189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowNullPointerException(NULL, "throw with null exception"); 96289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 96389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable()); 96489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 9661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 9671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::GOTO: 9681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::GOTO_16: 9691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::GOTO_32: { 9701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent uint32_t dex_pc = inst->GetDexPc(insns); 9711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent next_inst = Instruction::At(insns + dex_pc + dec_insn.vA); 97289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 97389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 97489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::PACKED_SWITCH: { 97533797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent uint32_t dex_pc = inst->GetDexPc(insns); 97689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const uint16_t* switch_data = insns + dex_pc + dec_insn.vB; 97789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t test_val = shadow_frame.GetVReg(dec_insn.vA); 97833797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature)); 979c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint16_t size = switch_data[1]; 98089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK_GT(size, 0); 98189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 98289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(IsAligned<4>(keys)); 98389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t first_key = keys[0]; 98489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]); 98589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(IsAligned<4>(targets)); 98689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = test_val - first_key; 98789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (index >= 0 && index < size) { 98889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + targets[index]); 98989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 99089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 991c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 992fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin case Instruction::SPARSE_SWITCH: { 99389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 99489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const uint16_t* switch_data = insns + dex_pc + dec_insn.vB; 99589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t test_val = shadow_frame.GetVReg(dec_insn.vA); 99689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature)); 99789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint16_t size = switch_data[1]; 99889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK_GT(size, 0); 99989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 100089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(IsAligned<4>(keys)); 10013302526f6276911b2dc40c731ea7fa0e7972d908Eric Laurent const int32_t* entries = keys + size; 100289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project CHECK(IsAligned<4>(entries)); 100389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int lo = 0; 100489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int hi = size - 1; 100589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project while (lo <= hi) { 100689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int mid = (lo + hi) / 2; 100789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t foundVal = keys[mid]; 100889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (test_val < foundVal) { 100989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project hi = mid - 1; 101033797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent } else if (test_val > foundVal) { 101189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project lo = mid + 1; 101289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 101389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + entries[mid]); 101489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 101589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 101689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 101789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 101889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 101989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::FILL_ARRAY_DATA: { 102089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 102189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(obj == NULL)) { 102289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA"); 10231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 10241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 10251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Array* array = obj->AsArray(); 10261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent DCHECK(array->IsArrayInstance() && !array->IsObjectArray()); 10271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent uint32_t dex_pc = inst->GetDexPc(insns); 10281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent const Instruction::ArrayDataPayload* payload = 10291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB); 10301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) { 103189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 103238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent "Ljava/lang/ArrayIndexOutOfBoundsException;", 10331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent "failed FILL_ARRAY_DATA; length=%d, index=%d", 103438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent array->GetLength(), payload->element_count); 103589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 10361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 1037c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint32_t size_in_bytes = payload->element_count * payload->element_width; 103889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes); 103989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 104089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 104189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_EQ: { 1042c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) { 104389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 10441703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 104589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 104689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 104789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 104889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_NE: { 104989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) { 105089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 105189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 105289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10532c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi break; 10541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 105589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_LT: { 10562c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) { 105789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 105889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 105989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 106089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 1061c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 10621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::IF_GE: { 106389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) { 106489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 106589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 106689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 106789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 106889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 106989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_GT: { 107089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) { 107189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 107289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 107389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 107489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 107589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 107689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_LE: { 107789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) { 1078c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent uint32_t dex_pc = inst->GetDexPc(insns); 1079c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1080c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 1081c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent break; 108289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 108389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_EQZ: { 108489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) == 0) { 10851dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent uint32_t dex_pc = inst->GetDexPc(insns); 108689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 108789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 108889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 108989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 109089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_NEZ: { 109189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) != 0) { 109289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 109389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 109489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 1095fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin break; 109689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 109789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_LTZ: { 109889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) < 0) { 109989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 110089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 110189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 110289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 110389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11048555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project case Instruction::IF_GEZ: { 11058555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) >= 0) { 11068555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 11078555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 11088555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project } 11098555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project break; 11108555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project } 11118555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project case Instruction::IF_GTZ: { 111289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) > 0) { 111389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 1114fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 111589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 111689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 111789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 111889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IF_LEZ: { 111989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (shadow_frame.GetVReg(dec_insn.vA) <= 0) { 112089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project uint32_t dex_pc = inst->GetDexPc(insns); 112189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 112289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 112389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 112489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 112589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::AGET_BOOLEAN: { 1126c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1127c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent if (UNLIKELY(a == NULL)) { 1128c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1129c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent break; 1130c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent } 113189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = shadow_frame.GetVReg(dec_insn.vC); 113289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, a->AsBooleanArray()->Get(index)); 113389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 113489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 113589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::AGET_BYTE: { 113689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 113789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(a == NULL)) { 1138d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 113989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 114089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 114189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = shadow_frame.GetVReg(dec_insn.vC); 114289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, a->AsByteArray()->Get(index)); 114389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 114489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 11451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::AGET_CHAR: { 11461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 11471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (UNLIKELY(a == NULL)) { 11481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 11491703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 115238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVReg(dec_insn.vA, a->AsCharArray()->Get(index)); 11531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::AGET_SHORT: { 11561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 11571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (UNLIKELY(a == NULL)) { 11581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 11591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 11621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent shadow_frame.SetVReg(dec_insn.vA, a->AsShortArray()->Get(index)); 11631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::AGET: { 11661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 11671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (UNLIKELY(a == NULL)) { 11681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 11691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 11721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent shadow_frame.SetVReg(dec_insn.vA, a->AsIntArray()->Get(index)); 11731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11741703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11759b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent case Instruction::AGET_WIDE: { 11769b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 11779b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent if (UNLIKELY(a == NULL)) { 11789b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 11799b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent break; 11809b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent } 11819b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 11829b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent shadow_frame.SetVRegLong(dec_insn.vA, a->AsLongArray()->Get(index)); 11831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::AGET_OBJECT: { 11869b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 11879b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent if (UNLIKELY(a == NULL)) { 11889b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 11891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 11921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent shadow_frame.SetVRegReference(dec_insn.vA, a->AsObjectArray<Object>()->Get(index)); 11931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 11941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 11951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::APUT_BOOLEAN: { 11961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent uint8_t val = shadow_frame.GetVReg(dec_insn.vA); 11971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 119838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (UNLIKELY(a == NULL)) { 11991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 12001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 12011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 12021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 12031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent a->AsBooleanArray()->Set(index, val); 12041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 12051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 12061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::APUT_BYTE: { 12071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int8_t val = shadow_frame.GetVReg(dec_insn.vA); 12081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 12091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (UNLIKELY(a == NULL)) { 12101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 12111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 12121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 12131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 12141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent a->AsByteArray()->Set(index, val); 12151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 12161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 12171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::APUT_CHAR: { 12181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent uint16_t val = shadow_frame.GetVReg(dec_insn.vA); 12191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 12201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent if (UNLIKELY(a == NULL)) { 12211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 12221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 12231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 12241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int32_t index = shadow_frame.GetVReg(dec_insn.vC); 12251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent a->AsCharArray()->Set(index, val); 12261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 12271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent } 12281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::APUT_SHORT: { 12291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent int16_t val = shadow_frame.GetVReg(dec_insn.vA); 123089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 123189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(a == NULL)) { 123289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 123389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 123489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 123589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = shadow_frame.GetVReg(dec_insn.vC); 123689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project a->AsShortArray()->Set(index, val); 123789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 123889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 123989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::APUT: { 1240d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent int32_t val = shadow_frame.GetVReg(dec_insn.vA); 124189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1242573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent if (UNLIKELY(a == NULL)) { 124389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 124489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 124589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 124689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = shadow_frame.GetVReg(dec_insn.vC); 124789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project a->AsIntArray()->Set(index, val); 124889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 124989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 125089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::APUT_WIDE: { 125189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int64_t val = shadow_frame.GetVRegLong(dec_insn.vA); 125289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 125389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(a == NULL)) { 125489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 125589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 125689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 125789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = shadow_frame.GetVReg(dec_insn.vC); 125889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project a->AsLongArray()->Set(index, val); 125989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 126089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 126189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::APUT_OBJECT: { 126289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* val = shadow_frame.GetVRegReference(dec_insn.vA); 126389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 126489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (UNLIKELY(a == NULL)) { 126589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 126689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 126789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 126889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project int32_t index = shadow_frame.GetVReg(dec_insn.vC); 126989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project a->AsObjectArray<Object>()->Set(index, val); 127089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 127189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 127289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IGET_BOOLEAN: 127338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean); 127489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 127554b1a0550411c2fd2084d82d28934d505c37349aMathias Agopian case Instruction::IGET_BYTE: 127654b1a0550411c2fd2084d82d28934d505c37349aMathias Agopian DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte); 127754b1a0550411c2fd2084d82d28934d505c37349aMathias Agopian break; 127838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::IGET_CHAR: 127989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar); 128089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 128189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IGET_SHORT: 128289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort); 128389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 128489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IGET: 128589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt); 128689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 128789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IGET_WIDE: 1288d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong); 128989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 129089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IGET_OBJECT: 129189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot); 129289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 129389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SGET_BOOLEAN: 129489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean); 129589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 129689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SGET_BYTE: 129789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte); 129889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 129989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SGET_CHAR: 130089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar); 130189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 130289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SGET_SHORT: 130389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort); 130489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 130533797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent case Instruction::SGET: 130638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt); 130733797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent break; 130889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SGET_WIDE: 130989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong); 131089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 131189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SGET_OBJECT: 131289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot); 131389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 131438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::IPUT_BOOLEAN: 131538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean); 131689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 131789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IPUT_BYTE: 131889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte); 131989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 132089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IPUT_CHAR: 132189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar); 1322d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 132389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IPUT_SHORT: 132489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort); 132589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 132634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent case Instruction::IPUT: 1327c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt); 132889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 132989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IPUT_WIDE: 133089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong); 133189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 133289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::IPUT_OBJECT: 133389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot); 133489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 133589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SPUT_BOOLEAN: 133689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean); 133789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 133889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SPUT_BYTE: 133989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte); 134089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 134189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SPUT_CHAR: 134289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar); 134389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 134489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SPUT_SHORT: 134589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort); 134689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 134789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SPUT: 134889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt); 134989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 135089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::SPUT_WIDE: 135189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong); 13521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent break; 13531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent case Instruction::SPUT_OBJECT: 13541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot); 135589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 135689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_VIRTUAL: 135789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register); 135889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 135989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_VIRTUAL_RANGE: 136089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register); 1361c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent break; 136289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_SUPER: 136389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register); 136489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 136589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_SUPER_RANGE: 136689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register); 136789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 136889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_DIRECT: 136989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register); 137089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 137189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_DIRECT_RANGE: 137289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register); 137389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 137489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_INTERFACE: 1375d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register); 137689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 137789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_INTERFACE_RANGE: 137889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register); 137989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 138089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_STATIC: 138189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register); 138289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 138389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INVOKE_STATIC_RANGE: 138489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register); 138589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 138689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::NEG_INT: 138789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB)); 1388d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent break; 138989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::NOT_INT: 139089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, ~shadow_frame.GetVReg(dec_insn.vB)); 139189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 139238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::NEG_LONG: 139338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB)); 139438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 139538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::NOT_LONG: 139638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegLong(dec_insn.vA, ~shadow_frame.GetVRegLong(dec_insn.vB)); 139738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 139889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::NEG_FLOAT: 139938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB)); 140089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 140138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::NEG_DOUBLE: 140238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB)); 140389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 140489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INT_TO_LONG: 140589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 140689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 140789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project case Instruction::INT_TO_FLOAT: 140889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 140938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 141038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::INT_TO_DOUBLE: 141138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 141238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 141338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::LONG_TO_INT: 141438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 141538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 141638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::LONG_TO_FLOAT: 141738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 141838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 141938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::LONG_TO_DOUBLE: 142038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 142138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent break; 142238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent case Instruction::FLOAT_TO_INT: { 142338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent float val = shadow_frame.GetVRegFloat(dec_insn.vB); 142438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent if (val != val) { 142538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVReg(dec_insn.vA, 0); 142638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent } else if (val > static_cast<float>(kMaxInt)) { 142738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent shadow_frame.SetVReg(dec_insn.vA, kMaxInt); 142889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else if (val < static_cast<float>(kMinInt)) { 142989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, kMinInt); 143089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } else { 143189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project shadow_frame.SetVReg(dec_insn.vA, val); 1432 } 1433 break; 1434 } 1435 case Instruction::FLOAT_TO_LONG: { 1436 float val = shadow_frame.GetVRegFloat(dec_insn.vB); 1437 if (val != val) { 1438 shadow_frame.SetVRegLong(dec_insn.vA, 0); 1439 } else if (val > static_cast<float>(kMaxLong)) { 1440 shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong); 1441 } else if (val < static_cast<float>(kMinLong)) { 1442 shadow_frame.SetVRegLong(dec_insn.vA, kMinLong); 1443 } else { 1444 shadow_frame.SetVRegLong(dec_insn.vA, val); 1445 } 1446 break; 1447 } 1448 case Instruction::FLOAT_TO_DOUBLE: 1449 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB)); 1450 break; 1451 case Instruction::DOUBLE_TO_INT: { 1452 double val = shadow_frame.GetVRegDouble(dec_insn.vB); 1453 if (val != val) { 1454 shadow_frame.SetVReg(dec_insn.vA, 0); 1455 } else if (val > static_cast<double>(kMaxInt)) { 1456 shadow_frame.SetVReg(dec_insn.vA, kMaxInt); 1457 } else if (val < static_cast<double>(kMinInt)) { 1458 shadow_frame.SetVReg(dec_insn.vA, kMinInt); 1459 } else { 1460 shadow_frame.SetVReg(dec_insn.vA, val); 1461 } 1462 break; 1463 } 1464 case Instruction::DOUBLE_TO_LONG: { 1465 double val = shadow_frame.GetVRegDouble(dec_insn.vB); 1466 if (val != val) { 1467 shadow_frame.SetVRegLong(dec_insn.vA, 0); 1468 } else if (val > static_cast<double>(kMaxLong)) { 1469 shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong); 1470 } else if (val < static_cast<double>(kMinLong)) { 1471 shadow_frame.SetVRegLong(dec_insn.vA, kMinLong); 1472 } else { 1473 shadow_frame.SetVRegLong(dec_insn.vA, val); 1474 } 1475 break; 1476 } 1477 case Instruction::DOUBLE_TO_FLOAT: 1478 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB)); 1479 break; 1480 case Instruction::INT_TO_BYTE: 1481 shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB))); 1482 break; 1483 case Instruction::INT_TO_CHAR: 1484 shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB))); 1485 break; 1486 case Instruction::INT_TO_SHORT: 1487 shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB))); 1488 break; 1489 case Instruction::ADD_INT: 1490 shadow_frame.SetVReg(dec_insn.vA, 1491 shadow_frame.GetVReg(dec_insn.vB) + shadow_frame.GetVReg(dec_insn.vC)); 1492 break; 1493 case Instruction::SUB_INT: 1494 shadow_frame.SetVReg(dec_insn.vA, 1495 shadow_frame.GetVReg(dec_insn.vB) - shadow_frame.GetVReg(dec_insn.vC)); 1496 break; 1497 case Instruction::MUL_INT: 1498 shadow_frame.SetVReg(dec_insn.vA, 1499 shadow_frame.GetVReg(dec_insn.vB) * shadow_frame.GetVReg(dec_insn.vC)); 1500 break; 1501 case Instruction::REM_INT: 1502 DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1503 shadow_frame.GetVReg(dec_insn.vC)); 1504 break; 1505 case Instruction::DIV_INT: 1506 DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1507 shadow_frame.GetVReg(dec_insn.vC)); 1508 break; 1509 case Instruction::SHL_INT: 1510 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << 1511 (shadow_frame.GetVReg(dec_insn.vC) & 0x1f)); 1512 break; 1513 case Instruction::SHR_INT: 1514 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> 1515 (shadow_frame.GetVReg(dec_insn.vC) & 0x1f)); 1516 break; 1517 case Instruction::USHR_INT: 1518 shadow_frame.SetVReg(dec_insn.vA, 1519 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >> 1520 (shadow_frame.GetVReg(dec_insn.vC) & 0x1f)); 1521 break; 1522 case Instruction::AND_INT: 1523 shadow_frame.SetVReg(dec_insn.vA, 1524 shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC)); 1525 break; 1526 case Instruction::OR_INT: 1527 shadow_frame.SetVReg(dec_insn.vA, 1528 shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC)); 1529 break; 1530 case Instruction::XOR_INT: 1531 shadow_frame.SetVReg(dec_insn.vA, 1532 shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC)); 1533 break; 1534 case Instruction::ADD_LONG: 1535 shadow_frame.SetVRegLong(dec_insn.vA, 1536 shadow_frame.GetVRegLong(dec_insn.vB) + 1537 shadow_frame.GetVRegLong(dec_insn.vC)); 1538 break; 1539 case Instruction::SUB_LONG: 1540 shadow_frame.SetVRegLong(dec_insn.vA, 1541 shadow_frame.GetVRegLong(dec_insn.vB) - 1542 shadow_frame.GetVRegLong(dec_insn.vC)); 1543 break; 1544 case Instruction::MUL_LONG: 1545 shadow_frame.SetVRegLong(dec_insn.vA, 1546 shadow_frame.GetVRegLong(dec_insn.vB) * 1547 shadow_frame.GetVRegLong(dec_insn.vC)); 1548 break; 1549 case Instruction::DIV_LONG: 1550 DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB), 1551 shadow_frame.GetVRegLong(dec_insn.vC)); 1552 break; 1553 case Instruction::REM_LONG: 1554 DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB), 1555 shadow_frame.GetVRegLong(dec_insn.vC)); 1556 break; 1557 case Instruction::AND_LONG: 1558 shadow_frame.SetVRegLong(dec_insn.vA, 1559 shadow_frame.GetVRegLong(dec_insn.vB) & 1560 shadow_frame.GetVRegLong(dec_insn.vC)); 1561 break; 1562 case Instruction::OR_LONG: 1563 shadow_frame.SetVRegLong(dec_insn.vA, 1564 shadow_frame.GetVRegLong(dec_insn.vB) | 1565 shadow_frame.GetVRegLong(dec_insn.vC)); 1566 break; 1567 case Instruction::XOR_LONG: 1568 shadow_frame.SetVRegLong(dec_insn.vA, 1569 shadow_frame.GetVRegLong(dec_insn.vB) ^ 1570 shadow_frame.GetVRegLong(dec_insn.vC)); 1571 break; 1572 case Instruction::SHL_LONG: 1573 shadow_frame.SetVRegLong(dec_insn.vA, 1574 shadow_frame.GetVRegLong(dec_insn.vB) << 1575 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f)); 1576 break; 1577 case Instruction::SHR_LONG: 1578 shadow_frame.SetVRegLong(dec_insn.vA, 1579 shadow_frame.GetVRegLong(dec_insn.vB) >> 1580 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f)); 1581 break; 1582 case Instruction::USHR_LONG: 1583 shadow_frame.SetVRegLong(dec_insn.vA, 1584 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >> 1585 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f)); 1586 break; 1587 case Instruction::ADD_FLOAT: 1588 shadow_frame.SetVRegFloat(dec_insn.vA, 1589 shadow_frame.GetVRegFloat(dec_insn.vB) + 1590 shadow_frame.GetVRegFloat(dec_insn.vC)); 1591 break; 1592 case Instruction::SUB_FLOAT: 1593 shadow_frame.SetVRegFloat(dec_insn.vA, 1594 shadow_frame.GetVRegFloat(dec_insn.vB) - 1595 shadow_frame.GetVRegFloat(dec_insn.vC)); 1596 break; 1597 case Instruction::MUL_FLOAT: 1598 shadow_frame.SetVRegFloat(dec_insn.vA, 1599 shadow_frame.GetVRegFloat(dec_insn.vB) * 1600 shadow_frame.GetVRegFloat(dec_insn.vC)); 1601 break; 1602 case Instruction::DIV_FLOAT: 1603 shadow_frame.SetVRegFloat(dec_insn.vA, 1604 shadow_frame.GetVRegFloat(dec_insn.vB) / 1605 shadow_frame.GetVRegFloat(dec_insn.vC)); 1606 break; 1607 case Instruction::REM_FLOAT: 1608 shadow_frame.SetVRegFloat(dec_insn.vA, 1609 fmodf(shadow_frame.GetVRegFloat(dec_insn.vB), 1610 shadow_frame.GetVRegFloat(dec_insn.vC))); 1611 break; 1612 case Instruction::ADD_DOUBLE: 1613 shadow_frame.SetVRegDouble(dec_insn.vA, 1614 shadow_frame.GetVRegDouble(dec_insn.vB) + 1615 shadow_frame.GetVRegDouble(dec_insn.vC)); 1616 break; 1617 case Instruction::SUB_DOUBLE: 1618 shadow_frame.SetVRegDouble(dec_insn.vA, 1619 shadow_frame.GetVRegDouble(dec_insn.vB) - 1620 shadow_frame.GetVRegDouble(dec_insn.vC)); 1621 break; 1622 case Instruction::MUL_DOUBLE: 1623 shadow_frame.SetVRegDouble(dec_insn.vA, 1624 shadow_frame.GetVRegDouble(dec_insn.vB) * 1625 shadow_frame.GetVRegDouble(dec_insn.vC)); 1626 break; 1627 case Instruction::DIV_DOUBLE: 1628 shadow_frame.SetVRegDouble(dec_insn.vA, 1629 shadow_frame.GetVRegDouble(dec_insn.vB) / 1630 shadow_frame.GetVRegDouble(dec_insn.vC)); 1631 break; 1632 case Instruction::REM_DOUBLE: 1633 shadow_frame.SetVRegDouble(dec_insn.vA, 1634 fmod(shadow_frame.GetVRegDouble(dec_insn.vB), 1635 shadow_frame.GetVRegDouble(dec_insn.vC))); 1636 break; 1637 case Instruction::ADD_INT_2ADDR: 1638 shadow_frame.SetVReg(dec_insn.vA, 1639 shadow_frame.GetVReg(dec_insn.vA) + shadow_frame.GetVReg(dec_insn.vB)); 1640 break; 1641 case Instruction::SUB_INT_2ADDR: 1642 shadow_frame.SetVReg(dec_insn.vA, 1643 shadow_frame.GetVReg(dec_insn.vA) - shadow_frame.GetVReg(dec_insn.vB)); 1644 break; 1645 case Instruction::MUL_INT_2ADDR: 1646 shadow_frame.SetVReg(dec_insn.vA, 1647 shadow_frame.GetVReg(dec_insn.vA) * shadow_frame.GetVReg(dec_insn.vB)); 1648 break; 1649 case Instruction::REM_INT_2ADDR: 1650 DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA), 1651 shadow_frame.GetVReg(dec_insn.vB)); 1652 break; 1653 case Instruction::SHL_INT_2ADDR: 1654 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) << 1655 (shadow_frame.GetVReg(dec_insn.vB) & 0x1f)); 1656 break; 1657 case Instruction::SHR_INT_2ADDR: 1658 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) >> 1659 (shadow_frame.GetVReg(dec_insn.vB) & 0x1f)); 1660 break; 1661 case Instruction::USHR_INT_2ADDR: 1662 shadow_frame.SetVReg(dec_insn.vA, 1663 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >> 1664 (shadow_frame.GetVReg(dec_insn.vB) & 0x1f)); 1665 break; 1666 case Instruction::AND_INT_2ADDR: 1667 shadow_frame.SetVReg(dec_insn.vA, 1668 shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB)); 1669 break; 1670 case Instruction::OR_INT_2ADDR: 1671 shadow_frame.SetVReg(dec_insn.vA, 1672 shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB)); 1673 break; 1674 case Instruction::XOR_INT_2ADDR: 1675 shadow_frame.SetVReg(dec_insn.vA, 1676 shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB)); 1677 break; 1678 case Instruction::DIV_INT_2ADDR: 1679 DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA), 1680 shadow_frame.GetVReg(dec_insn.vB)); 1681 break; 1682 case Instruction::ADD_LONG_2ADDR: 1683 shadow_frame.SetVRegLong(dec_insn.vA, 1684 shadow_frame.GetVRegLong(dec_insn.vA) + 1685 shadow_frame.GetVRegLong(dec_insn.vB)); 1686 break; 1687 case Instruction::SUB_LONG_2ADDR: 1688 shadow_frame.SetVRegLong(dec_insn.vA, 1689 shadow_frame.GetVRegLong(dec_insn.vA) - 1690 shadow_frame.GetVRegLong(dec_insn.vB)); 1691 break; 1692 case Instruction::MUL_LONG_2ADDR: 1693 shadow_frame.SetVRegLong(dec_insn.vA, 1694 shadow_frame.GetVRegLong(dec_insn.vA) * 1695 shadow_frame.GetVRegLong(dec_insn.vB)); 1696 break; 1697 case Instruction::DIV_LONG_2ADDR: 1698 DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA), 1699 shadow_frame.GetVRegLong(dec_insn.vB)); 1700 break; 1701 case Instruction::REM_LONG_2ADDR: 1702 DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA), 1703 shadow_frame.GetVRegLong(dec_insn.vB)); 1704 break; 1705 case Instruction::AND_LONG_2ADDR: 1706 shadow_frame.SetVRegLong(dec_insn.vA, 1707 shadow_frame.GetVRegLong(dec_insn.vA) & 1708 shadow_frame.GetVRegLong(dec_insn.vB)); 1709 break; 1710 case Instruction::OR_LONG_2ADDR: 1711 shadow_frame.SetVRegLong(dec_insn.vA, 1712 shadow_frame.GetVRegLong(dec_insn.vA) | 1713 shadow_frame.GetVRegLong(dec_insn.vB)); 1714 break; 1715 case Instruction::XOR_LONG_2ADDR: 1716 shadow_frame.SetVRegLong(dec_insn.vA, 1717 shadow_frame.GetVRegLong(dec_insn.vA) ^ 1718 shadow_frame.GetVRegLong(dec_insn.vB)); 1719 break; 1720 case Instruction::SHL_LONG_2ADDR: 1721 shadow_frame.SetVRegLong(dec_insn.vA, 1722 shadow_frame.GetVRegLong(dec_insn.vA) << 1723 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f)); 1724 break; 1725 case Instruction::SHR_LONG_2ADDR: 1726 shadow_frame.SetVRegLong(dec_insn.vA, 1727 shadow_frame.GetVRegLong(dec_insn.vA) >> 1728 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f)); 1729 break; 1730 case Instruction::USHR_LONG_2ADDR: 1731 shadow_frame.SetVRegLong(dec_insn.vA, 1732 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >> 1733 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f)); 1734 break; 1735 case Instruction::ADD_FLOAT_2ADDR: 1736 shadow_frame.SetVRegFloat(dec_insn.vA, 1737 shadow_frame.GetVRegFloat(dec_insn.vA) + 1738 shadow_frame.GetVRegFloat(dec_insn.vB)); 1739 break; 1740 case Instruction::SUB_FLOAT_2ADDR: 1741 shadow_frame.SetVRegFloat(dec_insn.vA, 1742 shadow_frame.GetVRegFloat(dec_insn.vA) - 1743 shadow_frame.GetVRegFloat(dec_insn.vB)); 1744 break; 1745 case Instruction::MUL_FLOAT_2ADDR: 1746 shadow_frame.SetVRegFloat(dec_insn.vA, 1747 shadow_frame.GetVRegFloat(dec_insn.vA) * 1748 shadow_frame.GetVRegFloat(dec_insn.vB)); 1749 break; 1750 case Instruction::DIV_FLOAT_2ADDR: 1751 shadow_frame.SetVRegFloat(dec_insn.vA, 1752 shadow_frame.GetVRegFloat(dec_insn.vA) / 1753 shadow_frame.GetVRegFloat(dec_insn.vB)); 1754 break; 1755 case Instruction::REM_FLOAT_2ADDR: 1756 shadow_frame.SetVRegFloat(dec_insn.vA, 1757 fmodf(shadow_frame.GetVRegFloat(dec_insn.vA), 1758 shadow_frame.GetVRegFloat(dec_insn.vB))); 1759 break; 1760 case Instruction::ADD_DOUBLE_2ADDR: 1761 shadow_frame.SetVRegDouble(dec_insn.vA, 1762 shadow_frame.GetVRegDouble(dec_insn.vA) + 1763 shadow_frame.GetVRegDouble(dec_insn.vB)); 1764 break; 1765 case Instruction::SUB_DOUBLE_2ADDR: 1766 shadow_frame.SetVRegDouble(dec_insn.vA, 1767 shadow_frame.GetVRegDouble(dec_insn.vA) - 1768 shadow_frame.GetVRegDouble(dec_insn.vB)); 1769 break; 1770 case Instruction::MUL_DOUBLE_2ADDR: 1771 shadow_frame.SetVRegDouble(dec_insn.vA, 1772 shadow_frame.GetVRegDouble(dec_insn.vA) * 1773 shadow_frame.GetVRegDouble(dec_insn.vB)); 1774 break; 1775 case Instruction::DIV_DOUBLE_2ADDR: 1776 shadow_frame.SetVRegDouble(dec_insn.vA, 1777 shadow_frame.GetVRegDouble(dec_insn.vA) / 1778 shadow_frame.GetVRegDouble(dec_insn.vB)); 1779 break; 1780 case Instruction::REM_DOUBLE_2ADDR: 1781 shadow_frame.SetVRegDouble(dec_insn.vA, 1782 fmod(shadow_frame.GetVRegDouble(dec_insn.vA), 1783 shadow_frame.GetVRegDouble(dec_insn.vB))); 1784 break; 1785 case Instruction::ADD_INT_LIT16: 1786 case Instruction::ADD_INT_LIT8: 1787 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC); 1788 break; 1789 case Instruction::RSUB_INT: 1790 case Instruction::RSUB_INT_LIT8: 1791 shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB)); 1792 break; 1793 case Instruction::MUL_INT_LIT16: 1794 case Instruction::MUL_INT_LIT8: 1795 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC); 1796 break; 1797 case Instruction::DIV_INT_LIT16: 1798 case Instruction::DIV_INT_LIT8: 1799 DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1800 dec_insn.vC); 1801 break; 1802 case Instruction::REM_INT_LIT16: 1803 case Instruction::REM_INT_LIT8: 1804 DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1805 dec_insn.vC); 1806 break; 1807 case Instruction::AND_INT_LIT16: 1808 case Instruction::AND_INT_LIT8: 1809 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC); 1810 break; 1811 case Instruction::OR_INT_LIT16: 1812 case Instruction::OR_INT_LIT8: 1813 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC); 1814 break; 1815 case Instruction::XOR_INT_LIT16: 1816 case Instruction::XOR_INT_LIT8: 1817 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC); 1818 break; 1819 case Instruction::SHL_INT_LIT8: 1820 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << 1821 (dec_insn.vC & 0x1f)); 1822 break; 1823 case Instruction::SHR_INT_LIT8: 1824 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> 1825 (dec_insn.vC & 0x1f)); 1826 break; 1827 case Instruction::USHR_INT_LIT8: 1828 shadow_frame.SetVReg(dec_insn.vA, 1829 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >> 1830 (dec_insn.vC & 0x1f)); 1831 break; 1832 default: 1833 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile()); 1834 break; 1835 } 1836 if (UNLIKELY(self->IsExceptionPending())) { 1837 self->VerifyStack(); 1838 ThrowLocation throw_location; 1839 mirror::Throwable* exception = self->GetException(&throw_location); 1840 uint32_t found_dex_pc = 1841 shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), inst->GetDexPc(insns)); 1842 if (found_dex_pc == DexFile::kDexNoIndex) { 1843 JValue result; 1844 result.SetJ(0); 1845 instrumentation->MethodUnwindEvent(self, shadow_frame.GetThisObject(), 1846 shadow_frame.GetMethod(), shadow_frame.GetDexPC()); 1847 return result; // Handler in caller. 1848 } else { 1849 Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(self, throw_location, 1850 shadow_frame.GetMethod(), 1851 found_dex_pc, exception); 1852 next_inst = Instruction::At(insns + found_dex_pc); 1853 } 1854 } 1855 inst = next_inst; 1856 } 1857} 1858 1859void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver, 1860 uint32_t* args, JValue* result) { 1861 DCHECK_EQ(self, Thread::Current()); 1862 if (__builtin_frame_address(0) < self->GetStackEnd()) { 1863 ThrowStackOverflowError(self); 1864 return; 1865 } 1866 1867 MethodHelper mh(method); 1868 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 1869 uint16_t num_regs; 1870 uint16_t num_ins; 1871 if (code_item != NULL) { 1872 num_regs = code_item->registers_size_; 1873 num_ins = code_item->ins_size_; 1874 } else if (method->IsAbstract()) { 1875 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 1876 self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;", 1877 "abstract method \"%s\"", PrettyMethod(method).c_str()); 1878 return; 1879 } else { 1880 DCHECK(method->IsNative()); 1881 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 1882 if (!method->IsStatic()) { 1883 num_regs++; 1884 num_ins++; 1885 } 1886 } 1887 // Set up shadow frame with matching number of reference slots to vregs. 1888 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 1889 UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs, 1890 last_shadow_frame, 1891 method, 0)); 1892 self->PushShadowFrame(shadow_frame.get()); 1893 size_t cur_reg = num_regs - num_ins; 1894 if (!method->IsStatic()) { 1895 CHECK(receiver != NULL); 1896 shadow_frame->SetVRegReference(cur_reg, receiver); 1897 ++cur_reg; 1898 } else if (!method->GetDeclaringClass()->IsInitializing()) { 1899 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), 1900 true, true)) { 1901 DCHECK(Thread::Current()->IsExceptionPending()); 1902 return; 1903 } 1904 CHECK(method->GetDeclaringClass()->IsInitializing()); 1905 } 1906 const char* shorty = mh.GetShorty(); 1907 for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 1908 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 1909 switch (shorty[shorty_pos + 1]) { 1910 case 'L': { 1911 Object* o = reinterpret_cast<Object*>(args[arg_pos]); 1912 shadow_frame->SetVRegReference(cur_reg, o); 1913 break; 1914 } 1915 case 'J': case 'D': { 1916 uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 1917 shadow_frame->SetVRegLong(cur_reg, wide_value); 1918 cur_reg++; 1919 arg_pos++; 1920 break; 1921 } 1922 default: 1923 shadow_frame->SetVReg(cur_reg, args[arg_pos]); 1924 break; 1925 } 1926 } 1927 if (LIKELY(!method->IsNative())) { 1928 JValue r = Execute(self, mh, code_item, *shadow_frame.get(), JValue()); 1929 if (result != NULL) { 1930 *result = r; 1931 } 1932 } else { 1933 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 1934 // generated stub) except during testing and image writing. 1935 if (!Runtime::Current()->IsStarted()) { 1936 UnstartedRuntimeJni(self, method, receiver, args, result); 1937 } else { 1938 InterpreterJni(self, method, shorty, receiver, args, result); 1939 } 1940 } 1941 self->PopShadowFrame(); 1942} 1943 1944void EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 1945 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1946 JValue value; 1947 value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 1948 MethodHelper mh; 1949 while (shadow_frame != NULL) { 1950 self->SetTopOfShadowStack(shadow_frame); 1951 mh.ChangeMethod(shadow_frame->GetMethod()); 1952 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 1953 value = Execute(self, mh, code_item, *shadow_frame, value); 1954 ShadowFrame* old_frame = shadow_frame; 1955 shadow_frame = shadow_frame->GetLink(); 1956 delete old_frame; 1957 } 1958 ret_val->SetJ(value.GetJ()); 1959} 1960 1961JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 1962 ShadowFrame& shadow_frame) 1963 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1964 DCHECK_EQ(self, Thread::Current()); 1965 if (__builtin_frame_address(0) < self->GetStackEnd()) { 1966 ThrowStackOverflowError(self); 1967 return JValue(); 1968 } 1969 1970 return Execute(self, mh, code_item, shadow_frame, JValue()); 1971} 1972 1973JValue EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame) 1974 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1975 if (__builtin_frame_address(0) < self->GetStackEnd()) { 1976 ThrowStackOverflowError(self); 1977 return JValue(); 1978 } 1979 1980 AbstractMethod* method = shadow_frame->GetMethod(); 1981 if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { 1982 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), 1983 true, true)) { 1984 DCHECK(Thread::Current()->IsExceptionPending()); 1985 return JValue(); 1986 } 1987 CHECK(method->GetDeclaringClass()->IsInitializing()); 1988 } 1989 1990 self->PushShadowFrame(shadow_frame); 1991 1992 MethodHelper mh(method); 1993 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 1994 JValue result; 1995 if (LIKELY(!method->IsNative())) { 1996 result = Execute(self, mh, code_item, *shadow_frame, JValue()); 1997 } else { 1998 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 1999 // generated stub) except during testing and image writing. 2000 CHECK(!Runtime::Current()->IsStarted()); 2001 Object* receiver = method->IsStatic() ? NULL : shadow_frame->GetVRegReference(0); 2002 uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 2003 UnstartedRuntimeJni(self, method, receiver, args, &result); 2004 } 2005 2006 self->PopShadowFrame(); 2007 return result; 2008} 2009 2010} // namespace interpreter 2011} // namespace art 2012